算法-刷题

《算法练习-文章汇总》

Day1:
爬楼梯:leetcode-70
https://leetcode-cn.com/problems/climbing-stairs/

Day2:
加一:leetcode-66
https://leetcode-cn.com/problems/plus-one/

Day3:
两数之和:leetcode-1
https://leetcode-cn.com/problems/two-sum/

【每日打卡链接】:https://jinshuju.net/f/LhtdPZ

Day4:
两两交换链表中的节点:leetcode-24
https://leetcode-cn.com/problems/swap-nodes-in-pairs/

【每日打卡链接】:https://jinshuju.net/f/LhtdPZ

Day5

合并两个有序链表:leetcode-21

https://leetcode-cn.com/problems/merge-two-sorted-lists/

【每日打卡链接】:https://jinshuju.net/f/LhtdPZ

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if(l1 == null){
            return l2;
        }else if(l2 == null){
            return l1;
        }else if(l1.val < l2.val){
            l1.next = mergeTwoLists(l1.next,l2);
            return l1;
        }else{
            l2.next = mergeTwoLists(l1,l2.next);
            return l2;
        }
    }
}

Day6
猜数字游戏
https://leetcode-cn.com/problems/bulls-and-cows/

【每日打卡链接】:https://jinshuju.net/f/LhtdPZ

public String getHint(String secret, String guess) {
    int A = 0;
    for (int i = 0; i < guess.length(); i++) {
        if (secret.charAt(i) == guess.charAt(i)) {
            A++;
        }
    }
    HashMap<Character, Integer> mapS = new HashMap<>();
    HashMap<Character, Integer> mapG = new HashMap<>();
    for (int i = 0; i < secret.length(); i++) {
        mapS.put(secret.charAt(i), mapS.getOrDefault(secret.charAt(i), 0) + 1);
        mapG.put(guess.charAt(i), mapG.getOrDefault(guess.charAt(i), 0) + 1);
    }
    int B = 0;
    for (Character key : mapG.keySet()) {
        int n1 = mapG.getOrDefault(key, 0);
        int n2 = mapS.getOrDefault(key, 0);
        B = B + Math.min(n1, n2);
    }
    return A + "A" + (B - A) + "B";
}

Day7:
设计循环双端队列https://leetcode-cn.com/problems/design-circular-deque/

class MyCircularDeque {
    private int capacity;
    private int[] arr;
    private int front;
    private int rear;
    /** Initialize your data structure here. Set the size of the deque to be k. */
    public MyCircularDeque(int k) {
        capacity = k + 1;
        arr = new int[capacity];
        front = 0;
        rear = 0;
    }
    
    /** Adds an item at the front of Deque. Return true if the operation is successful. */
    public boolean insertFront(int value) {
        if(isFull()) return false;
        front = (front - 1 +capacity)%capacity;
        arr[front] = value;
        return true;
    }
    
    /** Adds an item at the rear of Deque. Return true if the operation is successful. */
    public boolean insertLast(int value) {
         if(isFull()) return false;
         arr[rear] = value;
         rear = (rear+1)%capacity;
         return true;
    }
    
    /** Deletes an item from the front of Deque. Return true if the operation is successful. */
    public boolean deleteFront() {
        if(isEmpty()) return false;
        front = (front + 1)%capacity;
        return true;
    }
    
    /** Deletes an item from the rear of Deque. Return true if the operation is successful. */
    public boolean deleteLast() {
        if(isEmpty()) return false;
           rear = (rear - 1 + capacity)%capacity;
           return true;
    }
    
    /** Get the front item from the deque. */
    public int getFront() {
        if(isEmpty()) return -1;
        return arr[front];
    }
    
    /** Get the last item from the deque. */
    public int getRear() {
        if(isEmpty()) return -1;
        return arr[(rear-1+capacity)%capacity];
    }
    
    /** Checks whether the circular deque is empty or not. */
    public boolean isEmpty() {
         return front == rear;
    }
    
    /** Checks whether the circular deque is full or not. */
    public boolean isFull() {
          return (rear+1)%capacity == front;
    }
}

/**
 * Your MyCircularDeque object will be instantiated and called as such:
 * MyCircularDeque obj = new MyCircularDeque(k);
 * boolean param_1 = obj.insertFront(value);
 * boolean param_2 = obj.insertLast(value);
 * boolean param_3 = obj.deleteFront();
 * boolean param_4 = obj.deleteLast();
 * int param_5 = obj.getFront();
 * int param_6 = obj.getRear();
 * boolean param_7 = obj.isEmpty();
 * boolean param_8 = obj.isFull();
 */

Day8
两个数组的交集 II
https://leetcode-cn.com/problems/intersection-of-two-arrays-ii/
【每日打卡链接】:https://jinshuju.net/f/LhtdPZ

    public int[] intersect(int[] nums1, int[] nums2) {
        if (nums1.length > nums2.length) {
            return intersect(nums2, nums1);
        }
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        for (int num : nums1) {
            int count = map.getOrDefault(num, 0) + 1;
            map.put(num, count);
        }
        int[] intersection = new int[nums1.length];
        int index = 0;
        for (int num : nums2) {
            int count = map.getOrDefault(num, 0);
            if (count > 0) {
                intersection[index++] = num;
                count--;
                if (count > 0) {
                    map.put(num, count);
                } else {
                    map.remove(num);
                }
            }
        }
        return Arrays.copyOfRange(intersection, 0, index);
    }

@所有人
每日一题推荐:

♥️【Day9】

删除最外层的括号
https://leetcode-cn.com/problems/remove-outermost-parentheses/
【每日打卡链接】:https://jinshuju.net/f/LhtdPZ

    public String getParentString(String S){
        StringBuilder sb = new StringBuilder();
        int level = 0;
        for (Character c:S.toCharArray()){
            if (c == ')') --level;
            if (level>=1) sb.append(c);
            if (c == '(') ++level;
        }
        return sb.toString();
    }

@所有人
每日一题推荐:

♥️【Day10】

滑动窗口的最大值
https://leetcode-cn.com/problems/hua-dong-chuang-kou-de-zui-da-zhi-lcof/
【每日打卡链接】:https://jinshuju.net/f/LhtdPZ

public int[] maxSlidingWindow(int[] nums, int k) {
        int n = nums.length;
        if (n * k == 0) return new int[0];
        
        int [] output = new int[n - k + 1];
        for (int i = 0; i < n - k + 1; i++) {
            int max = Integer.MIN_VALUE;
            for(int j = i; j < i + k; j++) 
                max = Math.max(max, nums[j]);
            output[i] = max;
        }
        return output;
}

【Day13】

二叉树的最大深度

https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/
【每日打卡链接】:https://jinshuju.net/f/LhtdPZ

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public int maxDepth(TreeNode root) {
       if(root == null) return 0;
       int left_Depth = maxDepth(root.left);
       int right_Depth = maxDepth(root.right);
       return (left_Depth > right_Depth ? left_Depth:right_Depth)+1;
    }
}

【Day14】

  1. 移动零
    https://leetcode-cn.com/problems/move-zeroes/
void moveZeroes(int* nums, int numsSize){
    int i, k;
    int j = 0;
    for(i = 0;i< numsSize;i++){
          if(nums[i] != 0){
             nums[i] = k;
             nums[j] = nums[i];
             k = nums[j];
             j++;
          }
    }
}

【Day15】

  1. 二叉树的中序遍历
    https://leetcode-cn.com/problems/binary-tree-inorder-traversal/
    public List<Integer> inorderTraversal(TreeNode root) {
        ArrayList<Integer> res = new ArrayList<Integer>();
        helper(root,res);
        return res;
    }

    public void helper(TreeNode root,ArrayList<Integer> res){
        if(root != null){
            if(root.left != null){
                helper(root.left,res);
            }
            res.add(root.val);
            if(root.right != null){
                helper(root.right,res);
            }
        }
    }

@所有人
♥️每日一题推荐

【Day16】
剑指 Offer 05. 替换空格
https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/

    public String replaceSpace(String s) {
       s = s.replaceAll(" ","%20");
       return s;
    }

@所有人
♥️每日一题推荐

【Day17】每日一题推荐
从尾到头打印链表
https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof

  //从头到尾反过来返回每个节点的值
    public int[] reversePrint(ListNode head) {
        Stack<Integer> stack = new Stack<>();
        int n = 0;
        while (head !=null){
            stack.push(head.val);
            n++;
            head = head.next;
        }
        int[] res = new int[n];
        int i = 0;
        while (!stack.isEmpty()){
            res[i++] = stack.peek();
            stack.pop();
        }
        return res;
    }

@所有人
♥️每日一题推荐

【Day18】
面试题68 - II. 二叉树的最近公共祖先 https://leetcode-cn.com/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof/

递归解析:
终止条件:
当越过叶节点,则直接返回 nullnull ;
当 rootroot 等于 p, qp,q ,则直接返回 rootroot ;
递推工作:
开启递归左子节点,返回值记为 leftleft ;
开启递归右子节点,返回值记为 rightright ;
返回值: 根据 leftleft 和 rightright ,可展开为四种情况;
当 leftleft 和 rightright 同时为空 :说明 rootroot 的左 / 右子树中都不包含 p,qp,q ,返回 nullnull ;
当 leftleft 和 rightright 同时不为空 :说明 p, qp,q 分列在 rootroot 的 异侧 (分别在 左 / 右子树),因此 rootroot 为最近公共祖先,返回 rootroot ;
当 leftleft 为空 ,rightright 不为空 :p,qp,q 都不在 rootroot 的左子树中,直接返回 rightright 。具体可分为两种情况:
p,qp,q 其中一个在 rootroot 的 右子树 中,此时 rightright 指向 pp(假设为 pp );
p,qp,q 两节点都在 rootroot 的 右子树 中,此时的 rightright 指向 最近公共祖先节点 ;
当 leftleft 不为空 , rightright 为空 :与情况 3. 同理;

    //二叉树的最近公共祖先
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null || root == p || root == q) return root;
        TreeNode left = lowestCommonAncestor(root.left,p,q);
        TreeNode right = lowestCommonAncestor(root.right,p,q);
        if (left == null && right == null) return null;
        if (left == null) return right;
        if (right == null) return left;
        return root;
    }

【Day19】18. 四数之和(https://leetcode-cn.com/problems/4sum/)
https://leetcode-cn.com/problems/4sum/

四数之和与前面三数之和的思路几乎是一样的,嗝。(刚好前些天才写了三数之和的题解)
如果前面的三数之和会做了的话,这里其实就是在前面的基础上多添加一个遍历的指针而已。
会做三数之和的可以不用看下面的了。。

使用四个指针(a<b<c<d)。固定最小的a和b在左边,c=b+1,d=_size-1 移动两个指针包夹求解。
保存使得nums[a]+nums[b]+nums[c]+nums[d]==target的解。偏大时d左移,偏小时c右移。c和d相
遇时,表示以当前的a和b为最小值的解已经全部求得。b++,进入下一轮循环b循环,当b循环结束后。
a++,进入下一轮a循环。 即(a在最外层循环,里面嵌套b循环,再嵌套双指针c,d包夹求解)。

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
    sort(nums.begin(),nums.end());
    vector<std::vector<int> > res;
    if (nums.size()<4) {
        return res;
    }
    int a,b,c,d,_size = nums.size();
    for (a = 0; a<=_size-4; a++) {
        if (a>0 && nums[a] == nums[a-1]) continue;
        for (b=a+1; b<=_size-3; b++) {
            if (b>a+1 && nums[b] == nums[b-1]) continue;
            c=b+1,d=_size-1;
            while (c<d) {
                if (nums[a] + nums[b] + nums[c] + nums[d] < target) c++;
                else if (nums[a]+nums[b]+nums[c]+nums[d] > target) d--;
                else{
                    res.push_back({nums[a],nums[b],nums[c],nums[d]});
                    while (c<d && nums[c+1] == nums[c]) c++;
                    while (c<d && nums[d-1] == nums[d]) d--;
                    c++;
                    d--;
                }
            }
        }
    }
    return res;
    }
};

【Day20】三数之和(8月29日)
https://leetcode-cn.com/problems/3sum/

方法一:排序 + 双指针
题目中要求找到所有「不重复」且和为 00 的三元组,这个「不重复」的要求使得我们无法简单地使用三重循环枚举所有的三元组。这是因为在最坏的情况下,数组中的元素全部为 00,即

[0, 0, 0, 0, 0, ..., 0, 0, 0]
任意一个三元组的和都为 00。如果我们直接使用三重循环枚举三元组,会得到 O(N^3)O(N
3
) 个满足题目要求的三元组(其中 NN 是数组的长度)时间复杂度至少为 O(N^3)O(N
3
)。在这之后,我们还需要使用哈希表进行去重操作,得到不包含重复三元组的最终答案,又消耗了大量的空间。这个做法的时间复杂度和空间复杂度都很高,因此我们要换一种思路来考虑这个问题。

「不重复」的本质是什么?我们保持三重循环的大框架不变,只需要保证:

第二重循环枚举到的元素不小于当前第一重循环枚举到的元素;

第三重循环枚举到的元素不小于当前第二重循环枚举到的元素。

也就是说,我们枚举的三元组 (a, b, c)(a,b,c) 满足 a \leq b \leq ca≤b≤c,保证了只有 (a, b, c)(a,b,c) 这个顺序会被枚举到,而 (b, a, c)(b,a,c)、(c, b, a)(c,b,a) 等等这些不会,这样就减少了重复。要实现这一点,我们可以将数组中的元素从小到大进行排序,随后使用普通的三重循环就可以满足上面的要求。

同时,对于每一重循环而言,相邻两次枚举的元素不能相同,否则也会造成重复。举个例子,如果排完序的数组为

[0, 1, 2, 2, 2, 3]
^ ^ ^
我们使用三重循环枚举到的第一个三元组为 (0, 1, 2)(0,1,2),如果第三重循环继续枚举下一个元素,那么仍然是三元组 (0, 1, 2)(0,1,2),产生了重复。因此我们需要将第三重循环「跳到」下一个不相同的元素,即数组中的最后一个元素 33,枚举三元组 (0, 1, 3)(0,1,3)。

下面给出了改进的方法的伪代码实现:

nums.sort()
for first = 0 .. n-1
// 只有和上一次枚举的元素不相同,我们才会进行枚举
if first == 0 or nums[first] != nums[first-1] then
for second = first+1 .. n-1
if second == first+1 or nums[second] != nums[second-1] then
for third = second+1 .. n-1
if third == second+1 or nums[third] != nums[third-1] then
// 判断是否有 a+b+c==0
check(first, second, third)
这种方法的时间复杂度仍然为 O(N^3)O(N
3
),毕竟我们还是没有跳出三重循环的大框架。然而它是很容易继续优化的,可以发现,如果我们固定了前两重循环枚举到的元素 aa 和 bb,那么只有唯一的 cc 满足 a+b+c=0a+b+c=0。当第二重循环往后枚举一个元素 b'b

时,由于 b' > bb

b,那么满足 a+b'+c'=0a+b

+c

=0 的 c'c

一定有 c' < cc

<c,即 c'c

在数组中一定出现在 cc 的左侧。也就是说,我们可以从小到大枚举 bb,同时从大到小枚举 cc,即第二重循环和第三重循环实际上是并列的关系。

有了这样的发现,我们就可以保持第二重循环不变,而将第三重循环变成一个从数组最右端开始向左移动的指针,从而得到下面的伪代码:

nums.sort()
for first = 0 .. n-1
if first == 0 or nums[first] != nums[first-1] then
// 第三重循环对应的指针
third = n-1
for second = first+1 .. n-1
if second == first+1 or nums[second] != nums[second-1] then
// 向左移动指针,直到 a+b+c 不大于 0
while nums[first]+nums[second]+nums[third] > 0
third = third-1
// 判断是否有 a+b+c==0
check(first, second, third)
这个方法就是我们常说的「双指针」,当我们需要枚举数组中的两个元素时,如果我们发现随着第一个元素的递增,第二个元素是递减的,那么就可以使用双指针的方法,将枚举的时间复杂度从 O(N^2)O(N
2
) 减少至 O(N)O(N)。为什么是 O(N)O(N) 呢?这是因为在枚举的过程每一步中,「左指针」会向右移动一个位置(也就是题目中的 bb),而「右指针」会向左移动若干个位置,这个与数组的元素有关,但我们知道它一共会移动的位置数为 O(N)O(N),均摊下来,每次也向左移动一个位置,因此时间复杂度为 O(N)O(N)。

注意到我们的伪代码中还有第一重循环,时间复杂度为 O(N)O(N),因此枚举的总时间复杂度为 O(N^2)O(N
2
)。由于排序的时间复杂度为 O(N \log N)O(NlogN),在渐进意义下小于前者,因此算法的总时间复杂度为 O(N^2)O(N
2
)。

上述的伪代码中还有一些细节需要补充,例如我们需要保持左指针一直在右指针的左侧(即满足 b \leq cb≤c),具体可以参考下面的代码,均给出了详细的注释。

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
int n = nums.length;
        Arrays.sort(nums);
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        for (int first = 0;first<n;++first){
            //需要和上一次枚举的数不相同
            if (first>0 && nums[first] == nums[first-1]){
                continue;
            }
            //c对应的指针初始指向数组的最右端
            int third = n -1;
            int target = -nums[first];
            //枚举b
            for (int second = first + 1;second<n;++second){
                //需要和上一次枚举的数不相同
                if (second>first+1&&nums[second] == nums[second-1]){
                    continue;
                }
                //需要保证b的指针在c的指针的右侧
                while (second < third && nums[second] + nums[third] > target){
                    --third;
                }
                //如果指针重合,随着b后续的增加
                //就不会有满足a+b+c=0并且b<c的c了,可以退出循环
                if(second == third){
                    break;
                }
                if (nums[second] + nums[third] == target){
                    List<Integer> list = new ArrayList<Integer>();
                    list.add(nums[first]);
                    list.add(nums[second]);
                    list.add(nums[third]);
                    ans.add(list);
                }
            }
        }
        return ans;
    }
}

【Day21】面试题 17.09. 第 k 个数 (8月30日)
https://leetcode-cn.com/problems/get-kth-magic-number-lcci/

   /*
     * 核心思想:下一个数值,总是由上一个数值*3或5或7得到的,因此考虑三个数列:
     * 1、dp[0]*3,dp[1]*3,dp[2]*3,...
     * 2、dp[0]*5,dp[1]*5,dp[2]*5,...
     * 3、dp[0]*7,dp[1]*7,dp[2]*7,...
     * 将上面按照从小到大,合并到一起即可,如何做到这点,则需要设置三个指针,每个指针指向那种类型的最小值即可.
     * 初始状态:p3=0, p5=0, p7=0
     * dp[1] = Min(dp[p3]*3, dp[p5]*5, dp[p7]*7)
     *    Min(1*3, 1*5, 1*7)
     *    dp[1] = 3
     *    因此p3后移,即p3++,p3=1
     * dp[2] = Min(dp[p3]*3, dp[p5]*5, dp[7]*7)
     *    Min(3*3, 1*5, 1*7)
     *    dp[2] = 5
     *    因此p5后移,p5++,p5=1
     * dp[3] = Min(dp[p3]*3, dp[p5]*5, dp[p7]*7)
     *    Min(3*3, 3*5, 1*7)
     *    dp[3]=7
     *    因此p7后移,即p7++,p7=1
     * */

三指针+动态规划

class Solution {
    public int getKthMagicNumber(int k) {
        int dp[] = new int[k];
        int p3 = 0,p5=0,p7=0;
        dp[0] = 1;
        for (int i =1;i<k;i++){
            dp[i] = Math.min(Math.min(dp[p3]*3,dp[p5] * 5),dp[p7] * 7);//找到最小值
            //如果当前值与某类指针指向的值相同,则后移指针【每轮三个if判断必须都执行,防止排列组合之后是重复的值】
            if (dp[i] == dp[p3] * 3) p3++;
            if (dp[i] == dp[p5] * 5) p5++;
            if (dp[i] == dp[p7] * 7) p7++;
        }
        return dp[k-1];
    }
}

【Day22】46. 全排列 (8月31日)
https://leetcode-cn.com/problems/permutations/

class Solution {
    public List<List<Integer>> permute(int[] nums) {
         int len = nums.length;
         List<List<Integer>> res = new ArrayList<List<Integer>>();
         if(len == 0)return res;
         ArrayList<Integer> path = new ArrayList<Integer>();
         boolean[] used = new boolean[len];
         dfs(nums,len,0,path,used,res);
         return res;
    }
    public void dfs(int[] nums,Integer len,Integer depth,List<Integer>path,boolean[] used,List<List<Integer>> res){
        if(depth == len){
            res.add(new ArrayList(path));
            return;
        }
        for(int i = 0; i< len;i++){
            if(!used[i]){
                path.add(nums[i]);
                used[i] = true;
            
            dfs(nums,len,depth + 1,path,used,res);
            used[i] = false;
            path.remove(path.size() - 1);
            }
        }
    }
}

【Day23】509. 斐波那契数 (9月1日)
https://leetcode-cn.com/problems/fibonacci-number/

class Solution {
    public int fib(int N) {
        if(N == 0 || N == 1) return N;
        int m = N-1;
        int n = N-2;
        int sum = fib(m) + fib(n);
        return sum;
    }
}
O(2^n)
O(n)

class Solution {
    public int fib(int N) {
        if(N == 0 || N == 1) return N;
        if(N==2) return 1;
        int m = 1;
        int n = 1;
        int res = 0;
        for(int i = 3;i<=N;i++){
            res = m + n;
            n = m;
            m = res;
        }
        return res;
    }
}
O(n)
O(1)

【Day24】122. 买卖股票的最佳时机 (9月2日)
II https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/description/

//贪心算法
class Solution {
    public int maxProfit(int[] prices) {
        int len = prices.length;
        if(len < 2) return 0;
        int res = 0;
        for(int i = 1;i<len;i++){
            int diff = prices[i] - prices[i-1];
            if(diff > 0){
                res += diff;
            }
        }
        return res;
    }
}

【Day25】860. 柠檬水找零 (9月3日)
https://leetcode-cn.com/problems/lemonade-change/description/

【Day26】200. 岛屿数量 (9月4日)
https://leetcode-cn.com/problems/number-of-islands/

【Day27】367. 有效的完全平方数 (9月5日)
https://leetcode-cn.com/problems/valid-perfect-square/

【Day28】169. 多数元素 (9月6日)
https://leetcode-cn.com/problems/majority-element/

【Day29】127. 单词接龙
https://leetcode-cn.com/problems/word-ladder/description/

【Day30】560. 和为K的子数组 (9月8日)
https://leetcode-cn.com/problems/subarray-sum-equals-k/

【Day31】874. 模拟行走机器人
https://leetcode-cn.com/problems/walking-robot-simulation/description/

【Day32】53. 最大子序和 (9月10日)
https://leetcode-cn.com/problems/maximum-subarray/

【Day33】1143. 最长公共子序列 (9月11日)
https://leetcode-cn.com/problems/longest-common-subsequence/

【Day34】74. 搜索二维矩阵
https://leetcode-cn.com/problems/search-a-2d-matrix/

【Day35】剑指 Offer 05. 替换空格
https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/

【Day36】64. 最小路径和 (9月14日)
https://leetcode-cn.com/problems/minimum-path-sum/

【Day37】322. 零钱兑换 (9.15)
https://leetcode-cn.com/problems/coin-change/

【Day38】213. 打家劫舍 II (9.16)
https://leetcode-cn.com/problems/house-robber-ii/description/

【Day39】

  1. N叉树的前序遍历 (9.17)
    https://leetcode-cn.com/problems/n-ary-tree-preorder-traversal/description/

【Day40】363. 矩形区域不超过 K 的最大数值和 (9.18)
https://leetcode-cn.com/problems/max-sum-of-rectangle-no-larger-than-k/

【Day41】33. 搜索旋转排序数组 (9.19)
https://leetcode-cn.com/problems/search-in-rotated-sorted-array/

【Day42】212. 单词搜索 II
https://leetcode-cn.com/problems/word-search-ii/

【Day43】240. 搜索二维矩阵 II (9.21)
https://leetcode-cn.com/problems/search-a-2d-matrix-ii/

【Day44】208. 实现 Trie (前缀树) (9.22)
https://leetcode-cn.com/problems/implement-trie-prefix-tree/

【Day45】130. 被围绕的区域 https://leetcode-cn.com/problems/surrounded-regions/

【Day46】152. 乘积最大子数组 https://leetcode-cn.com/problems/maximum-product-subarray/

【Day47】126. 单词接龙 II https://leetcode-cn.com/problems/word-ladder-ii/

【Day48】16. 最接近的三数之和 https://leetcode-cn.com/problems/3sum-closest/

【Day49】22. 括号生成 https://leetcode-cn.com/problems/generate-parentheses/

【Day50】547. 朋友圈
https://leetcode-cn.com/problems/friend-circles/

【Day51】633. 平方数之和 https://leetcode-cn.com/problems/sum-of-square-numbers/

【Day52】198. 打家劫舍 https://leetcode-cn.com/problems/house-robber/

【Day56】718. 最长重复子数组 https://leetcode-cn.com/problems/maximum-length-of-repeated-subarray/

【Day57】387. 字符串中的第一个唯一字符 https://leetcode-cn.com/problems/first-unique-character-in-a-string/

【Day58】62. 不同路径 https://leetcode-cn.com/problems/unique-paths/

【Day59】541. 反转字符串 II https://leetcode-cn.com/problems/reverse-string-ii/

【Day60】300. 最长上升子序列 (10月8日)
https://leetcode-cn.com/problems/longest-increasing-subsequence/

【Day61】371. 两整数之和
https://leetcode-cn.com/problems/sum-of-two-integers/

【Day62】680. 验证回文字符串 Ⅱ https://leetcode-cn.com/problems/valid-palindrome-ii/

【Day63】32. 最长有效括号 (10月10日)
https://leetcode-cn.com/problems/longest-valid-parentheses/

【Day64】83. 删除排序链表中的重复元素
https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list/

【Day65】120. 三角形最小路径和
https://leetcode-cn.com/problems/triangle/

【Day69】238. 除自身以外数组的乘积
https://leetcode-cn.com/problems/product-of-array-except-self/

【Day70】76. 最小覆盖子串 https://leetcode-cn.com/problems/minimum-window-substring/

【Day71 】130. 被围绕的区域
https://leetcode-cn.com/problems/surrounded-regions/

【Day72 】1. 两数之和
https://leetcode-cn.com/problems/two-sum/

【Day73 】20. 有效的括号
https://leetcode-cn.com/problems/valid-parentheses/

【Day74】394. 字符串解码
https://leetcode-cn.com/problems/decode-string/

【Day75 】146. LRU缓存机制
https://leetcode-cn.com/problems/lru-cache/

【Day76】 208. 实现 Trie (前缀树)
https://leetcode-cn.com/problems/implement-trie-prefix-tree/

【Day77 】211. 添加与搜索单词 - 数据结构设计
https://leetcode-cn.com/problems/design-add-and-search-words-data-structure/

【Day78】 389. 找不同
https://leetcode-cn.com/problems/find-the-difference/

【Day79】 290. 单词规律
https://leetcode-cn.com/problems/word-pattern/

【Day80】387. 字符串中的第一个唯一字符
https://leetcode-cn.com/problems/first-unique-character-in-a-string/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容