算法-刷题

作者: 一亩三分甜 | 来源:发表于2020-08-20 02:21 被阅读0次

    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/

    相关文章

      网友评论

        本文标题:算法-刷题

        本文链接:https://www.haomeiwen.com/subject/gbbjjktx.html