Leetcode每日刷题笔记--JAVA版(边做边更新)

按照题目选择

模板

二叉搜索

//二叉树搜索
    public void binarySearch(TreeNode root) {
        //返回条件
        //return ;

        /*
        这里写前序遍历的操作
         */
        binarySearch(root.left);

        /*
        这里写中序遍历的操作
         */
        binarySearch(root.right);

        /*
        这里写后序遍历的操作
         */

        //返回
        return;
    }

n叉树的搜索

  //n叉树搜索
    public void nSearch(NNodeTree root) {
        //返回条件
        //return ;

        /*
        这里写前序遍历的操作
         */

        for (int i = 0; i < root.children.length; i++) {
            nSearch(root.children[i]);
            /*
            这里写中序遍历的操作
            */
        }

        /*
        这里写后序遍历的操作
         */

        //返回
        return;
    }

回溯算法(Back Track)

 //回溯算法
    public List<List<Integer>> res = new ArrayList<>();
    public void backTrack(int[] nums, LinkedList<Integer> track) {
        if (track.size() == nums.length) {
            res.add(track);
            return;
        }

        for (int i = 0; i < nums.length; i++) {
            if (track.contains(i))
                continue;
            track.add(nums[i]);
            backTrack(nums, track);
            track.removeLast();
        }
    }

动态规划(Dynamic Programming)

动态规划问题主要考的是一种看问题的思考方式

 //动态规划
    public void dynamicProgramming(int[] num, int target) {
        int[] dp = new int[num.length];
        for (int i = 0; i < num.length; i++) {
//            for (int j = 0; j < ; j++) {
            //状态转移方程
            //条件判断
//                dp[i]=
//            }
        }
    }

广度优先搜索(BFS)

 //广度优先搜索
    public void bfs(TreeNode root, TreeNode target) {
        if (root == null) {
            return;
        }
        //队列
        Queue<TreeNode> queue = new LinkedList<>();
        //哈希表记录已经访问过的节点
        //如果是二叉树就不需要了
        Set<TreeNode> isVisited = new HashSet<>();

        //先初始化一下
        queue.offer(root);
        isVisited.add(root);

        while (!queue.isEmpty()) {
            TreeNode cur = queue.poll();
            if (cur == target) return;

            queue.add(root.left);
            queue.add(root.right);
            //如果是多叉树
//            for (int i = 0; i < root.children.lenth; i++) {
//                if(!isVisited.contains(root[i]){
//                  queue.offer(root[i]);
//                  isVisited.add(root[i]);
//                  }
//            }
            //步数++
        }
        //返回数值
        return;
    }

双指针(Two Pointer)

//双指针1:判断链表的环
    boolean hasCycle(ListNode head) {
        ListNode fast, slow;
        fast = slow = head;
        while (head != null && head.next != null) {
            fast = fast.next.next;
            slow = slow.next;
            if (slow == fast)
                return true;
        }
        return false;
    }
    //双指针2:判断链表的环的交点
    ListNode detectCycle(ListNode head) {
        ListNode fast, slow;
        fast = slow = head;
        while (head != null && head.next != null) {
            fast = fast.next.next;
            slow = slow.next;
            if (slow == fast)
                break;
        }
        slow = head;
        while (slow != fast) {
            slow = slow.next;
            fast = fast.next;
        }
        return slow;
    }

    //双指针3:左右指针
    //典型的是二分查找
    int binarySearch(int[] nums, int target){
        if(nums.length==0)return -1;
        int left =0,right =nums.length-1;
        while (left<=right){
            int mid = left+(right-left)>>1;
            if (nums[mid] == target) {
                return mid;
            }else if(nums[mid]<target){
                left=mid+1;
            }else if(nums[mid]>target){
                right=mid-1;
            }
        }
        return -1;
    }

滑动窗口(Sliding Window)

  //滑动窗口
    void slidingWindow(String s ,String t){
        Map<Character,Integer> map = new HashMap<>();
        Map<Character,Integer> need = new HashMap<>();
        for (char c : t.toCharArray()) {
            need.put(c,need.getOrDefault(c,0)+1);
        }

        int left=0,right = 0;
        char[] chars = s.toCharArray();
        while (right != s.length()) {
            //处理逻辑

            while (true/*这里写缩小的条件*/){
                //处理逻辑
            }
        }
        return;

    }

一些例题

下面是我刚开始按照顺序刷算法的一些题目。刷了一周感觉效果不是特别好,所以就按照例题刷。后来学了一些模板再去看问题,真的会很不一样!

1. Two Sum

202121/9/6
在这里插入图片描述

技巧:使用HashMap将集合的数保存

public int[] twoSum(int[] nums, int target) {
     HashMap<Integer, Integer> Sites = new HashMap<Integer, Integer>();
        for (int i = 0; i < nums.length; i++) {
            int sum = target - nums[i];
            if (Sites.containsKey(sum)) {
                return new int[]{i, Sites.get(sum)};
            }
            Sites.put(nums[i], i);
        }
        throw new IllegalArgumentException("No two sum solution");
    }

2.Add Two Numbers

202121/9/7
在这里插入图片描述
这题解法很常见。因为两个两位数相加,进位位只可能是0或者1,在每个节点创建时,我们只需要加上前一位数的进位位和本位之和。注释已经写的很详细啦~

/**
 * 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 addTwoNumbers(ListNode l1, ListNode l2) {
    ListNode headNode = new ListNode(0);//头结点
    ListNode  tempNode = headNode;//临时用来操作的节点
    int carry = 0;//保存进位
    //如果遍历两个链表时,值都是空的话,才退出,否则继续执行操作
    while (l1 != null || l2!= null) {
    //由于两个链表的长度不同,所以我们得定义变量来进行算数
    //因为while循环会导致一个空指针
    //如果为空指针,加数或者被加数为0即可
        int x = (l1 != null) ? l1.val : 0;
        int y = (l2 != null) ? l2.val : 0;
        //这里算出加上前一位数进位位的和
        int sum = carry + x + y;
        //算出这一位的进位位
        carry = sum / 10;
        //sum % 10 保证在10以内
        tempNode.next = new ListNode(sum % 10);
        //新链表的指针移动
        tempNode = tempNode.next;
        //判定是否为空,空就不移动
        //这里如果两个链表不一样长,就会出现空值
        if (l1 != null) l1 = l1.next;
        if (l2 != null) l2 = l2.next;
    }
    //最后如果有进位位的话,记得加载尾节点
    if (carry > 0) {
        tempNode.next = new ListNode(carry);
    }
    return headNode.next;
    }
}

在这里插入图片描述
这种数组的方式效率极低,需要双重for

我们使用List优化

 public String convert(String s, int numRows) {

        if (numRows == 1) return s;

        List<StringBuilder> rows = new ArrayList<>();
        for (int i = 0; i < Math.min(numRows, s.length()); i++)
            rows.add(new StringBuilder());

        int curRow = 0;
        boolean goingDown = false;

        for (char c : s.toCharArray()) {
            rows.get(curRow).append(c);
            if (curRow == 0 || curRow == numRows - 1) goingDown = !goingDown; //遍历到两端,改变方向
            curRow += goingDown ? 1 : -1;
        }

        StringBuilder ret = new StringBuilder();
        for (StringBuilder row : rows) ret.append(row);
        return ret.toString();
    }

在这里插入图片描述

3 . Longest Substring Without Repeating Characters

(https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/)
2021/9/8
在这里插入图片描述
这里最先想到的是暴力枚举所有的可能性,不过这肯定不是最好的算法。
之后想到了跟第一题一样,用Map。Key是字符,head记录头节点到哪了,tail记录尾节点,Value是给定的下标,然后判断是否在之前添加过,如果存在,保存一下这个Key的Value数值,相应的就是head,然后添加后面重复的字符。最后输出的就是head和tail的差值。

 public static int lengthOfLongestSubstring(String s) {
        int n = s.length(), ans = 0;
        Map<Character, Integer> map = new HashMap<>();
        for (int j = 0, i = 0; j < n; j++) {
            if (map.containsKey(s.charAt(j))) {
                i = Math.max(map.get(s.charAt(j)), i);
            }
            ans = Math.max(ans, j - i + 1);
            map.put(s.charAt(j), j + 1);//下标 + 1 代表 i 要移动的下个位置
        }
        return ans;
}

2021/9/9-9/12

这三天要打数模,先不更三天哈。

4.Median of Two Sorted Arrays

https://leetcode-cn.com/problems/median-of-two-sorted-arrays/
2021/9/14
昨天写了代码太过混乱,还没解出来,今天补上。
在这里插入图片描述
我们合并两个数组存放在一个新的数组,最后直接取数组的中间数。

     int[] result;
        int anum = nums1.length;
        int bnum = nums2.length;
        result = new int[anum + bnum];
        if (anum == 0) {
            if (bnum % 2 == 0) {
                return (nums2[bnum / 2 - 1] + nums2[bnum / 2]) / 2.0;
            } else {

                return nums2[bnum / 2];
            }
        }
        if (bnum == 0) {
            if (anum % 2 == 0) {
                return (nums1[anum / 2 - 1] + nums1[anum / 2]) / 2.0;
            } else {
                return nums1[anum / 2];
            }
        }

        //用来计信数组里的数
        int count = 0;
        int i = 0, j = 0;
        //新的数组还没到达两个数组之和
        while (count != (anum + bnum)) {
            if (i == anum) {
                //第一个数组已经遍历完了,但是还能继续遍历第二个数组
                while (j != bnum) {
                    result[count++] = nums2[j++];
                }
                break;
            }
            if (j == bnum) {
                //第二个数组已经遍历完了,但是还能继续遍历第一个数组
                while (i != anum) {
                    result[count++] = nums1[i++];
                }
                break;
            }

            if (nums1[i] < nums2[j]) {
                //数组二大
                result[count++] = nums1[i++];
            } else {
                //数组一大
                //这里要是两个数一样,同样只添加一个数,这里是个坑
                result[count++] = nums2[j++];
            }
        }
        //判断结果数组是不是双数
        if (count % 2 == 0) {
           //双数情况需要中间两个数求平均
            return (result[count / 2 - 1] + result[count / 2]) / 2.0;
        } else {
            //单数直接返回一半
            return result[count / 2];
        }

5.Longest Palindrome

9/15
https://leetcode-cn.com/problems/longest-palindromic-substring/submissions/
在这里插入图片描述

暴力解法,遍历每一次字符,每次遍历都核对一下是否是回文字符。但是时间复杂度O(n`3)太大,并没有通过。

public  static  String longestPalindrome(String s) {
    if (s.length() == 1) {
        return s;
    }
    String targetS=String.valueOf(s.charAt(0));
    boolean findIt=false ;
    int j =0;
    //只需要长度-1次
    for (int i = 0; i < s.length(); i++) {
        for (j = i+1; j <= s.length() ; j++) {
            String tempS;
            tempS = s.substring(i,j);
            findIt = checkPalindrome(tempS);
            if (findIt ==true){
                if (targetS.length()<tempS.length()){
                    targetS=tempS;
                }
            }
        }
    }
    return targetS;
      return String.valueOf(s.charAt(0));
}
private static boolean checkPalindrome(String rome) {
    System.out.println("rome====>"+rome);
    int tail = rome.length()-1;
    int start =0;
    if (start == tail) {
        return false;
    }
    for (int i = start; i < rome.length(); i++) {
        if (i >= tail){
            return true;
        }
        if (rome.charAt(i)!= rome.charAt(tail)) {
            return false;
        }
        tail--;
    }
    return true;
}

方法二是寻找最长公共子串的方法:
https://blog.csdn.net/u010397369/article/details/38979077
先暂时写到这啦。

6.ZigZag Conversion

9/16
https://leetcode-cn.com/problems/zigzag-conversion/

在这里插入图片描述
讲解图晚点传上来哈

 public String convert(String s, int numRows) {
        int hor = 1, ver = 0;
        if (s.length() == 1 || numRows == 1) {
            return s;
        }
        int verNum = ((s.length() - numRows) / (numRows - 1)) + 1;
        if (numRows + (verNum - 1) * (numRows - 1) != s.length()) {
            verNum++;
        }
        char[][] arr = new char[numRows][verNum];
        for (int i = 0; i < numRows; i++) {
            for (int j = 0; j < verNum; j++) {
                arr[i][j] = '1';
            }
        }
        arr[0][0] = s.charAt(0);
        boolean isUp = false;
        int i = 1;
        while (i < s.length()) {
            arr[hor][ver] = s.charAt(i);
            if (i == s.length() - 1) {
                break;
            }
            if (hor == numRows - 1) {
                //说明要向上走
                ver++;
                // arr[hor][ver]='1';
                hor--;
                i++;
                arr[hor][ver] = s.charAt(i);
                isUp = true;
            }
            if (i == s.length() - 1) {
                break;
            }
            if (hor == 0) {
                //说明要向下走
                ver++;
                // arr[hor][ver]='1';
                hor++;
                i++;
                arr[hor][ver] = s.charAt(i);
                isUp = hor == numRows - 1;
            }
            if (isUp) {
                //向上走
                hor--;
                i++;
            } else {
                hor++;
                i++;
            }

        }
        String result = new String();
        for (int m = 0; m < numRows; m++) {
            for (int j = 0; j < verNum; j++) {
                if (arr[m][j] != '1') {
                    result += arr[m][j];
                }
            }

        }
        return result;
    }

7.Reverse Integer

9/17
https://leetcode-cn.com/problems/reverse-integer/

这道题比较简单

    public int reverse(int x) {
   int result = 0;
        while (x != 0) {
            if (result>Integer.MAX_VALUE/10) return 0;
            if (result<Integer.MIN_VALUE/10) return 0;
            result*=10;
            result += x % 10;
            x /= 10;
        }
        return result;
       }

8.String To Integer

https://leetcode-cn.com/problems/string-to-integer-atoi/
感觉这题主要是考对于一些条件的 判断。

int sign = 1;
        int result = 0, temp = 0;
        boolean hasSign = false; //代表是否开始转换数字
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == '-' && !hasSign) {
                sign = -1;
                hasSign = true;
                continue;
            }
            if (s.charAt(i) == '+' && !hasSign) {
                sign = 1;
                hasSign = true;
                continue;
            }
            if (s.charAt(i) == ' ' && !hasSign) {
                continue;
            }

            if (s.charAt(i) >= '0' && s.charAt(i) <= '9') {
                hasSign = true;
                temp = s.charAt(i) - '0';
                //这里题目有个坑
                //不判断>7根本过不了
                if (result * sign > Integer.MAX_VALUE / 10 || (result * sign == Integer.MAX_VALUE / 10 && temp * sign > 7))
                    return 2147483647;
                if (result * sign < Integer.MIN_VALUE / 10 || (result * sign == Integer.MIN_VALUE / 10 && temp * sign < -8))
                    return -2147483648;
                result = result * 10 + temp;
            } else {
                return result * sign;
            }
        }
        return result * sign;

9.Palindrome Number

https://leetcode-cn.com/problems/palindrome-number/
9/22
在这里插入图片描述
这题比较简单,直接比较数字的后半段和前半段是否一样

 public static boolean isPalindrome(int x) {
        //提前排除掉一些结果
        if (x < 0 || (x % 10 == 0 && x != 0)) {
            return false;
        }
        int reverseNum = 0;
        int len = (int) (Math.log(x) / Math.log(10) + 1);
        for (int i = 0; i < len / 2; i++) {
            //这里跟前面的题一样,需要判断是否大于2147483647 或小于-2147483648
            if(reverseNum>Integer.MAX_VALUE/10||reverseNum<Integer.MIN_VALUE/10) return false;
            reverseNum=reverseNum*10+x%10;
            System.out.println(reverseNum);
            x/=10;
        }
        //位数为偶的情况
        if(len%2==0&&x==reverseNum) return true;
        if (len%2!=0&&x/10==reverseNum) return true;
        return false;

    }

在这里我们可以看到,我们需要算出x的位数,能不能再优化一下呢?

  public boolean isPalindrome(int x) {
     if (x < 0 || (x % 10 == 0 && x != 0)) {
            return false;
        }
        int reverseNum = 0;
        //这里我们直接对x进行操作只需要比较x和reverseNum的大小即可
        while (x > reverseNum) {
            if (reverseNum > Integer.MAX_VALUE / 10 || reverseNum < Integer.MIN_VALUE / 10) return false;
            reverseNum=reverseNum*10+x%10;
            x/=10;
        }
        //x为偶数位的情况||x为奇数位的情况
        return reverseNum==x||reverseNum/10==x;
    }

10.Regular Expression Matching

https://leetcode-cn.com/problems/regular-expression-matching/
9/23
在这里插入图片描述
这道题刚开始理解错题意了,没做出来。刚开始想的是找到 p 中的跟 s 相同的子串也返回true。结果看来别人的题解才发现只能是在. 和 *左右下,s 和 p 相同才返回 true。

利用递归的方式:先不加*的写法写出来

 public static boolean isMatch(String s, String p) {
 //因为我们会对s和p删除操作,并且p一定需要比s长,所以出口就是判断p是否为空
 //p空了s还有字符说明没有实现一一对应的关系,返回false
 //p和s同时空了,就说明匹配了
       if (p.isEmpty()) return s.isEmpty();
       //这里需要判断s是否为空,空了的话下一条return语句就不会继续substring
       //后面判断字符是否相同或者p出现了”.“
       boolean firstCheck = !s.isEmpty() && (p.charAt(0) == '.' || s.charAt(0) == p.charAt(0));
       //返回上面的判断以及继续寻找后面的字符是否相等
       return firstCheck && isMatch(s.substring(1), p.substring(1));
}

没有加*的模式很容易,再来看看加了这个条件的

   public static boolean isMatch(String s, String p) {

//前面都一样
        if (p.isEmpty()) return s.isEmpty();

        boolean first_match = (!s.isEmpty() &&
                (p.charAt(0) == s.charAt(0) || p.charAt(0) == '.'));
        //只有长度大于 2 的时候,才考虑 *
        //第二个字符是*
        if (p.length() >= 2 && p.charAt(1) == '*') {
            //两种情况
            //p 直接跳过两个字符。表示 * 前边的字符出现 0 次
            //p 不变,例如 s = aa ,p = a*,第一个 a 匹配,然后 s的第二个 a 接着和 p 的第一个 a 进行匹配。表示 * 用前一个字符替代。
            //这里优点耗费时间,两种情况都遍历
            return (isMatch(s, p.substring(2)) ||
                    (first_match && isMatch(s.substring(1), p)));
        } else {
        //这里和之前一样
            return first_match && isMatch(s.substring(1), p.substring(1));
        }
    }

13.Roman To Int

https://leetcode-cn.com/problems/roman-to-integer/
9/24
在这里插入图片描述这题比较简单,想到的第一个方法就是将原有的数存在哈希表中,Key 是字符,Value 是对应的 10 进制数,遍历寻找。

    public int romanToInt(String s) {
        Map<Character, Integer> map = new HashMap<>();
        map.put('I', 1);
        map.put('V', 5);
        map.put('X', 10);
        map.put('L', 50);
        map.put('C', 100);
        map.put('D', 500);
        map.put('M', 1000);

        int result = 0;
        for (int i = 0; i < s.length(); i++) {
            int temp = map.get(s.charAt(i));
            if (i < s.length() - 1) {
                //说明有可能出现减法
                int tempNext = map.get(s.charAt(i + 1));
                if (tempNext > temp) {
                    result += (tempNext - temp);
                    //跳过这两个字符,不再继续执行
                    i++;
                    continue;
                }
            }
            //不存在该字符比下一个字符大的情况、最后一位数的处理方式
            result += temp;

        }
        return result;
    }

我们呢还能不用哈希表来做:

  public static int romanToInt(String s) {
        int result =0;
        int i =0;
        //判断是否存在减法的数,存在就将其加入结果,并且删去这两个字符
        if((i=s.indexOf("IV"))!=-1){
            result+=4;
            s= s.substring(0, i)+s.substring(i+2);
        }
        if((i=s.indexOf("IX"))!=-1){
            result+=9;
            s= s.substring(0, i)+s.substring(i+2);
        }
        if((i=s.indexOf("XL"))!=-1){
            result+=40;
            s= s.substring(0, i)+s.substring(i+2);
        }
        if((i=s.indexOf("XC"))!=-1){
            result+=90;
            s= s.substring(0, i)+s.substring(i+2);
        }
        if((i=s.indexOf("CD"))!=-1){
            result+=400;
            s= s.substring(0, i)+s.substring(i+2);
        }
        if((i=s.indexOf("CM"))!=-1){
            result+=900;
            s= s.substring(0, i)+s.substring(i+2);
        }
        //最后再遍历一下,按照正常输出就可以了;
        for (int i1 = 0; i1 < s.length(); i1++) {
            switch (s.charAt(i1)){
                case 'I':
                    result+=1;
                    break;
                case 'V':
                    result+=5;
                    break;
                case 'X':
                    result+=10;
                    break;
                case 'L':
                    result+=50;
                    break;
                case 'C':
                    result+=100;
                    break;
                case 'D':
                    result+=500;
                    break;
                case 'M':
                    result+=1000;
                    break;
            }
        }
        return result;
    }

可以看到,我们使用s.subStirng的时候需要时间,如何不用它呢

public int romanToInt(String s) {
     int sum=0;
     //直接减去少的值(注意这里需要减两倍差值),我们后面遍历就可以直接加上每个罗马数字应该有的数值了
    if(s.indexOf("IV")!=-1){sum-=2;}
    if(s.indexOf("IX")!=-1){sum-=2;}
    if(s.indexOf("XL")!=-1){sum-=20;}
    if(s.indexOf("XC")!=-1){sum-=20;}
    if(s.indexOf("CD")!=-1){sum-=200;}
    if(s.indexOf("CM")!=-1){sum-=200;}

    char c[]=s.toCharArray();
    int count=0;

   for(;count<=s.length()-1;count++){
       if(c[count]=='M') sum+=1000;
       if(c[count]=='D') sum+=500;
       if(c[count]=='C') sum+=100;
       if(c[count]=='L') sum+=50;
       if(c[count]=='X') sum+=10;
       if(c[count]=='V') sum+=5;
       if(c[count]=='I') sum+=1;

   }

   return sum;

}

11. Container With Most Water

这题比较简单,只需要每次算出最大值,保存一下即可。
看可以优化的点就是那两个while,如果小的那一个数比之前最短的还小,可直接跳过

public static int maxArea(int[] height) {
            int i = 0, j = height.length - 1,max = 0;
            while(i < j) {
                int h = Math.min(height[i], height[j]);
                max = Math.max(max, (j - i) * h);
                while (height[i] <= h && i < j)
                    i++;
                while (height[j] <= h && i < j)
                    j--;
            }
            return max;
        }

12. Integer To Roman

9/26
https://leetcode-cn.com/problems/integer-to-roman/
在这里插入图片描述

思路简单,直接把罗马数和我们的数对应写出来,挨个比对,对完就减小一下num。

  public static String intToRoman(int num){
        int []values = new int[]{1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
        String []symble= new String[]{"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
        StringBuilder res=new StringBuilder("");
        int i=0;
        while (num > 0) {
            while (values[i] > num) {
                i++;
            }
            num-=values[i];
            res.append(symble[i]);
        }
        return res.toString();
    }

15 ThreeSum

https://leetcode-cn.com/problems/3sum/
在这里插入图片描述
这题可以用到双指针。
解法一:先将数据排序,固定一个指针,另外两个在头和尾部,符合条件就载入容器。
这题的难点在于需要去重。

 public List<List<Integer>> threeSum(int[] nums) {
            nums = sort(nums);
        if (nums == null || nums.length == 0) {
            return new ArrayList<>();
        }
        List<Integer> innerList;
        List<List<Integer>> outerList = new ArrayList<>();
        int j = 1;
        while (j < nums.length - 1) {
            int start = 0;
            int end = nums.length - 1;
            if (j > 1 && nums[j] == nums[j - 1]) {
                start = j - 1;
            }
            while (start < j && end > j) {
                if (start > 0 && nums[start - 1] == nums[start]) {
                    //相同的情况
                    start++;
                    continue;
                }
                if (end < nums.length - 1 && nums[end + 1] == nums[start]) {
                    end--;
                    continue;
                }
                int and = nums[start] + nums[end] + nums[j];
                if (and == 0) {
                    innerList = new ArrayList<>();
                    innerList.add(nums[start]);
                    innerList.add(nums[end]);
                    innerList.add(nums[j]);
                    outerList.add(innerList);
                    start++;
                    end--;
                } else if (and < 0) {
                    start++;
                } else {
                    end--;
                }
            }
            j++;
        }
        return outerList;
    }
       private static int [] sort(int[] nums) {
        int temp =0;
        for (int i = 0; i < nums.length-1; i++) {
            for (int j = 0; j <nums.length-i-1 ; j++) {
                if(nums[j]>nums[j+1]){
                    temp=nums[j];
                    nums[j]=nums[j+1];
                    nums[j+1]=temp;
                }
            }
        }
        return nums;
    }

解法二,力扣时间超过99%的解法。先桶排序,然后双指针,利用这两个指针判断第三个值存不存在,存在就加入列表,当然这里用到了桶,直接判断就行。

import java.util.*;
class Solution {
    public static List<List<Integer>> threeSum(int[] nums) {
        if (nums.length < 3) return List.of();
        int min = nums[0], max = min, size = 0;
        for (int num : nums)
            if (num < min) min = num;
            else if (num > max) max = num;
        if (min > 0 || max < 0) return List.of();
        int[] sorted = new int[max - min + 1];
        for (int num : nums) sorted[num - min]++;
        for (int i = min; i <= max; i++)
            if (sorted[i - min] > 0) nums[size++] = i;
        List<List<Integer>> res = new ArrayList<>();
        for (int i = 0, ni; (ni = nums[i]) < 0; i++) {
            for (int j = size - 1, nj, t; (t = -ni - (nj = nums[j])) <= nj; j--) {
                if (t >= ni)
                    if (t == ni) {
                        if (sorted[ni - min] > 1) res.add(new IntList(ni, t, nj));
                    } else if (t == nj) {
                        if (sorted[nj - min] > 1) res.add(new IntList(ni, t, nj));
                    } else if (sorted[t - min] > 0) res.add(new IntList(ni, t, nj));
            }
        }
        if (sorted[-min] >= 3) res.add(new IntList(0, 0, 0));
        return res;
    }
    static class IntList extends AbstractList<Integer> {
        private int[] values;
        public IntList(int... values) {
            this.values = values;
        }
        public Integer get(int index) {
            return values[index];
        }
        public int size() {
            return values.length;
        }
    }
}

16 Three Sum Closest

https://leetcode-cn.com/problems/3sum-closest/submissions/
在这里插入图片描述
这一题和上一题略微有点不同,要找到最接近的target的三数和。
这里只需要把三数和保存一下,然后对比target。

  public static int threeSumClosest(int[] nums, int target) {
        Arrays.sort(nums);
        int deff = Integer.MAX_VALUE;
        int result =0;
        for (int head = 0; head < nums.length - 2; head++) {
            if (head > 0 && nums[head] == nums[head - 1]) {
                continue;
            }
            for (int j = head + 1, tail = nums.length - 1; j < tail; ) {
                int sum = nums[head] + nums[tail] + nums[j];
                if (Math.abs(sum - target) < deff) {
                    result=sum;
                    deff = Math.abs(sum - target);
                }
                if (sum == target) {
                    return result;
                } else if (sum > target) {
                    tail--;
                } else {
                    j++;
                }
            }
        }
        return result;
    }

18. Four Sum

https://leetcode-cn.com/problems/4sum/
在这里插入图片描述

和三数相加、两数相加没什么大的区别,就多加了一层的for(多加一个指针)

 public List<List<Integer>> fourSum(int[] nums, int target) {
         List<List<Integer>> quadruplets = new ArrayList<List<Integer>>();
        if (nums == null || nums.length < 4) {
            return quadruplets;
        }
        Arrays.sort(nums);
        int length = nums.length;
        for (int i = 0; i < length - 3; i++) {
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }
            if (nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) {
                break;
            }
            if (nums[i] + nums[length - 3] + nums[length - 2] + nums[length - 1] < target) {
                continue;
            }
            for (int j = i + 1; j < length - 2; j++) {
                if (j > i + 1 && nums[j] == nums[j - 1]) {
                    continue;
                }
                if (nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target) {
                    break;
                }
                if (nums[i] + nums[j] + nums[length - 2] + nums[length - 1] < target) {
                    continue;
                }
                int left = j + 1, right = length - 1;
                while (left < right) {
                    int sum = nums[i] + nums[j] + nums[left] + nums[right];
                    if (sum == target) {
                        quadruplets.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
                        while (left < right && nums[left] == nums[left + 1]) {
                            left++;
                        }
                        left++;
                        while (left < right && nums[right] == nums[right - 1]) {
                            right--;
                        }
                        right--;
                    } else if (sum < target) {
                        left++;
                    } else {
                        right--;
                    }
                }
            }
        }
        return quadruplets;
    }

LinkedList

19.Remove Nth Node From End of List

https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/
在这里插入图片描述

代码很简单,就是要注意一下细节方面

public static ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode temp= new ListNode(0,head);
        int length = 0;
        while (temp.next != null) {
            length++;
            temp=temp.next;
        }
        if(n==1&&length==1)return null;
       temp= new ListNode(0,head);
        ListNode temp2=temp;
        length=length-n;
        while (length > 1) {
            temp=temp.next;
            length--;
        }
        temp.next=temp.next.next;
        return temp2.next;
    }

21.MergeTwo Sorted Lists

https://leetcode-cn.com/problems/merge-two-sorted-lists/
在这里插入图片描述

    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if(l1==null){
            return l2;
        }
        if(l2==null){
            return l1;
        }
        if(l1.val<l2.val){
            l1.next=mergeTwoLists(l1.next,l2);
            return l1;
        }else {
             l2.next=mergeTwoLists(l1,l2.next);
            return l2;

        }
    }

23.Merge k Sorted Lists

https://leetcode-cn.com/problems/merge-k-sorted-lists/
在这里插入图片描述

public static ListNode mergeKLists(ListNode []lists) {
        if(lists.length==0){
            return null;
        }
        if(lists.length==1){
            return lists[0];
        }
        if(lists.length==2){
            return mergeTwoLists(lists[0],lists[1]);
        }
        ListNode []left = new ListNode[lists.length/2];
        for (int i = 0; i < left.length; i++) {
            left[i]=lists[i];
        }
        ListNode []right = new ListNode[lists.length-lists.length/2];
        for (int i = 0; i < left.length; i++) {
            right[i]=lists[i+ left.length];
        }
        return mergeTwoLists(mergeKLists(left),mergeKLists(right));
    }
    public static ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if(l1==null){
            return l2;
        }
        if(l2==null){
            return l1;
        }
        if(l1.val<l2.val){
            l1.next=mergeTwoLists(l1.next,l2);
            return l1;
        }else {
             l2.next=mergeTwoLists(l1,l2.next);
            return l2;

        }
    }

24.Swap Nodes in Pairs

https://leetcode-cn.com/problems/swap-nodes-in-pairs/
在这里插入图片描述
这里普通方法的话是直接两个两个交换,另外一种优美的方法是递归。
当然,由于列表的值是顺序排序的,而且是自然数,所以可以直接更改val也行。

//递归方式
 public ListNode swapPairs(ListNode head) {
 if(head==null||head.next==null)return head;
        ListNode next = head.next;
        head.next=swapPairs(next.next);
        next.next = head;
        return next;
    }

五行代码解决~

25.Reverse Nodes in k-Group

  public ListNode reverseKGroup(ListNode head, int k) {
  if(head==null)return head;
        ListNode cur = head;
        ListNode prev = null;
        ListNode next=null;
        int count = 0;
        int num=0;
        while (num < k && cur != null) {
            cur = cur.next;
            num++;
        }
        if (num>=k){
            //反转
                        cur = head;
            while (cur!=null&&count<k){
                next=cur.next;
                cur.next =prev;
                prev=cur;
                cur=next;
                count++;
            }
            if(next!=null){
            head.next=reverseKGroup(next,k);
            }
            return prev;
        }else {
            //数量不够不反转
            return head;
        }
    }

61 Rotate List

https://leetcode-cn.com/problems/rotate-list/
在这里插入图片描述

   public ListNode rotateRight(ListNode head, int k) {
        if(head == null || head.next == null) return head;
        if(k == 0) return head;
        ListNode tail = head, newtail = head;
        ListNode newhead;
        int n = 1;
        // 原来的尾结点指向原来的头结点,形成环
        while(tail.next != null){
            tail = tail.next;
            n++;
        }
        tail.next = head;
        // 找到断开环的位置
        for(int i = 0; i < (n - k % n - 1); i++){
            newtail = newtail.next;
        }
        // 新的头结点指向断开环的位置
        newhead = newtail.next;
        newtail.next = null;

        return newhead;
    }

Stak

20 Valid Parentheses

https://leetcode-cn.com/problems/valid-parentheses/
在这里插入图片描述

    public boolean isValid(String s) {
        Stack<Character> stack = new Stack<Character>();
        for (char c : s.toCharArray()) {
            if(c=='{')stack.push('}');
            else if(c=='[')stack.push(']');
            else if(c=='(')stack.push(')');
            else if(stack.isEmpty()||c!=stack.pop()) return false;
        }
        return stack.isEmpty();
    }

* 42 Trapping Rain Water

https://leetcode-cn.com/problems/trapping-rain-water/
在这里插入图片描述

   public static int trap(int[] height) {
        Stack<Integer> stack = new Stack<>();
        int result =0;
        for (int i = 0; i < height.length; i++) {
            while(!stack.isEmpty()&&height[i]>height[stack.peek()]){
                int top = stack.pop();
                if (stack.isEmpty()) {
                    break;
                }
                int left = stack.peek();
                int wide =i-left-1;
                int high = Math.min(height[left],height[i])-height[top];
                result+=wide*high;
            }
            stack.push(i);
        }
        return result;
    }
    
   public int trap(int[] height) {
        int all = 0;
        int left = 0;
        int right = height.length - 1;
        int leftMax = height[left];
        int rightMax = height[right];
        while(left <= right){
            if(leftMax <= rightMax){
                leftMax = Math.max(leftMax, height[left]);
                all += leftMax - height[left++];
            }else{
                rightMax = Math.max(rightMax, height[right]);
                all += rightMax - height[right--];
            }
        }
        return all;
    }

71 .Simplify Path

https://leetcode-cn.com/problems/simplify-path/
在这里插入图片描述

//利用split函数讲路径提取出来,然后利用栈保存数据,最后加上题目的一些条件即可
public String simplifyPath(String path) {
    String[] split = path.trim().split("/");
        Stack<String> stack = new Stack<>();
        for (int i = 0; i < split.length; i++) {
            if(split[i].equals("..")){
                if(!stack.isEmpty()){
                 //返回前一个
                    stack.pop();
                }
            }else {
                if(!split[i].equals(".")&&!split[i].equals("")){
                    stack.push(split[i]);
                }
            }
        }
        if (stack.isEmpty()) {
            return "/";
        }else{
            String res = "";
            for (String s : stack) {
                res+="/"+s;
            }
            return res;
        }
    }

*84 Largest Rectangle In Histogram

https://leetcode-cn.com/problems/largest-rectangle-in-histogram/
在这里插入图片描述
这题比较好的思想很重要。如果height[0~i] 里放的全是递增的,height[i+1]height[i]小 ,那我们怎么处理?是不是直接从i开始一直往前找最大的即可。

  public int largestRectangleArea(int[] heights) {
  int[] tmp = new int[heights.length + 2];
        System.arraycopy(heights, 0, tmp, 1, heights.length);
        Deque<Integer> stack = new ArrayDeque<>();
        int area = 0;
        for (int i = 0; i < tmp.length; i++) {
            while (!stack.isEmpty()&&tmp[i]<tmp[stack.peek()]){
                int h =tmp[stack.pop()];
                area  = Math.max(area,(i-stack.peek()-1)*h);
            }
            stack.push(i);
        }
        return area;
    }

Tree

92 Binary Tree Inorder Traversal

https://leetcode-cn.com/problems/binary-tree-inorder-traversal/
在这里插入图片描述

public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> inner = new ArrayList<>();
        if (root == null) {
            return inner;
        }
        inner.addAll(inorderTraversal(root.left));
        inner.add(root.val);
        inner.addAll(inorderTraversal(root.right));
        return inner;
    }

*95 Unique Binary Search Trees II

https://leetcode-cn.com/problems/unique-binary-search-trees-ii/
在这里插入图片描述

    public List<TreeNode> generateTrees(int n) {
return myGenerateTrees(1,n);
    }
      private List<TreeNode> myGenerateTrees(int start, int end) {
        List<TreeNode> res= new ArrayList<>();
        if(start>end){
        res.add(null);
        return res;
        }

        for (int i = start; i <= end; i++) {
            List<TreeNode> leftTree = myGenerateTrees(start, i - 1);
            List<TreeNode> rightTree = myGenerateTrees(i+1,end);
            for (TreeNode left : leftTree) {
                for (TreeNode right : rightTree) {
                    TreeNode curTree = new TreeNode(i);
                    curTree.left=left;
                    curTree.right=right;
                    res.add(curTree);
                }
            }
        }
        return res;
    }

*96 Unique Binary Search Trees

https://leetcode-cn.com/problems/unique-binary-search-trees/
在这里插入图片描述

//不需要考虑是不是搜索树
 public int numTrees(int n) {
        int[] dp=new int[n+1];
        dp[0]=1;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= i; j++) {
                dp[i] += dp[j - 1] * dp[i - j];
            }
        }
        return dp[n];
    }

98 Validate Binary Search Tree

https://leetcode-cn.com/problems/validate-binary-search-tree/
在这里插入图片描述

 public boolean isValidBST(TreeNode root) {
     return mIsValidBST(root,Long.MIN_VALUE,Long.MAX_VALUE);
       }

    private boolean mIsValidBST(TreeNode root, long minValue, long maxValue) {
        if(root==null)return true;
        if(root.val<=minValue||root.val>=maxValue)return false;
        return mIsValidBST(root.left,minValue,root.val)&&mIsValidBST(root.right,root.val,maxValue);
    }

*99 Recover Binary Search Tree

https://leetcode-cn.com/problems/recover-binary-search-tree/
在这里插入图片描述

public void recoverTree(TreeNode root) {
        Deque<TreeNode> stack = new ArrayDeque<TreeNode>();
        TreeNode x = null, y = null, pred = null;

        while (!stack.isEmpty() || root != null) {
            while (root != null) {
                stack.push(root);
                root = root.left;
            }
            root = stack.pop();
            if (pred != null && root.val < pred.val) {
                y = root;
                if (x == null) {
                    x = pred;
                } else {
                    break;
                }
            }
            pred = root;
            root = root.right;
        }

        swap(x, y);
    }
public void swap(TreeNode x, TreeNode y) {
        int tmp = x.val;
        x.val = y.val;
        y.val = tmp;
    }
    
//不用栈的方式
public void recoverTree(TreeNode root) {
        if (root==null||root.left==null&&root.right==null)return;
        dfs(root);
        int temp = n1.val;
        n1.val=n2.val;
        n2.val=temp;
        return;
    }

    private void dfs(TreeNode cur){
        if(cur==null)return;
        dfs(cur.left);
        if (pre != null && pre.val > cur.val) {
            if (n1 == null) n1 = pre;
            n2 = cur;
        }
        pre=cur;
        dfs(cur.right);

    }

100 Same Tree

https://leetcode-cn.com/problems/same-tree/
在这里插入图片描述

   public boolean isSameTree(TreeNode p, TreeNode q) {
        if(p==null&&q==null)return true;
        if(p==null||q==null) return false;
        return p.val==q.val&&isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);
    }

101 Symmetric Tree

https://leetcode-cn.com/problems/symmetric-tree/
在这里插入图片描述

 public boolean isSymmetric(A92BinaryTreeInorderTraversal.TreeNode root) {
        return doSomething(root.left,root.right);
    }

    private boolean doSomething(A92BinaryTreeInorderTraversal.TreeNode left, A92BinaryTreeInorderTraversal.TreeNode right) {
        if(left==null&&right==null)return true;
        if(left==null||right==null)return false;
        return left.val==right.val&&doSomething(left.left,right.right)&&doSomething(left.right,right.left);
    }

102 Binary Tree Level Order Traversal

https://leetcode-cn.com/problems/binary-tree-level-order-traversal/
在这里插入图片描述

   public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> lists= new ArrayList<>(new ArrayList<>());
        if(root==null)return lists;
        return myLevleOrder(root,1,lists);
    }

    private List<List<Integer>> myLevleOrder(TreeNode root, int i,List<List<Integer>> lists) {
        if(root==null)return lists;
        if (lists.size()<i) {
            lists.add(new ArrayList<>());
        }
        lists.get(i).add(root.val);
        myLevleOrder(root.left,i+1,lists);
        myLevleOrder(root.right,i+1,lists);
        return lists;
    }

103 Binary Tree Zigzag Level Order Traversal

https://leetcode-cn.com/problems/binary-tree-zigzag-level-order-traversal/
在这里插入图片描述
代码很简单,就是上面一题的原本方法,获得完链表之后就判断是否需要翻转就行。

 public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        List<List<Integer>> lists = new ArrayList<>();
        mZigzagLevelOrder(lists, 1, root);
        for (int i = 0; i < lists.size(); i++) {
            if (i % 2 != 0)
                Collections.reverse(lists.get(i));
        }
        return lists;
    }

    private void mZigzagLevelOrder(List<List<Integer>> lists, int i, TreeNode root) {
        if (root == null) return;
        if (lists.size() < i) lists.add(new ArrayList<>());
        lists.get(i-1).add(root.val);
        mZigzagLevelOrder(lists, i + 1, root.left);
        mZigzagLevelOrder(lists, i + 1, root.right);
        return;
    }

104 Maximum Depth Of Binary Tree

https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/
在这里插入图片描述

 public int maxDepth(TreeNode root) {
      if(root==null)return 0;
      return Math.max(maxDepth(root.left),maxDepth(root.right))+1;
    }

*105 Construct Binary Tree From Preorder And Inorder Traversal

https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
在这里插入图片描述
千言万语汇于一图中,主要是需要找到规律。
在这里插入图片描述

   public TreeNode buildTree(int[] preorder, int[] inorder) {
        Map<Integer,Integer> map = new HashMap<>();
        for (int i = 0; i < preorder.length; i++) {
            map.put(inorder[i],i);
        }
        return buildTree(preorder,map,0,preorder.length-1,0,inorder.length-1);
    }

    private TreeNode buildTree(int[] preorder, Map<Integer, Integer> pMap, int preLeft, int preRight, int inLeft, int inRight) {
        if(preLeft>preRight||inLeft>inRight)return null;
        TreeNode root = new TreeNode(preorder[preLeft]);
        int rootIndex = pMap.get(preorder[preLeft]);
        root.left=buildTree(preorder,pMap,preLeft+1,rootIndex-inLeft+preLeft,inLeft,rootIndex-1);
        root.right=buildTree(preorder,pMap,rootIndex-inLeft+preLeft+1,preRight,rootIndex+1,inRight);
        return root;
    }

144 Binary Tree Preorder Traversal

https://leetcode-cn.com/problems/binary-tree-preorder-traversal/
在这里插入图片描述

  public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        return pre(root,list);
    }
    public List<Integer> pre(TreeNode root,List<Integer>list){
        if(root==null)return list;
        list.add(root.val);
        pre(root.left,list);
        pre(root.right,list);
        return list;
    }

226 Invert Binary Tree

https://leetcode-cn.com/problems/invert-binary-tree/
在这里插入图片描述

  public TreeNode invertTree(TreeNode root) {
        if(root==null)return null;
        TreeNode left =invertTree(root.left);
        TreeNode right = invertTree(root.right);
        root.left=right;
        root.right=left;
        return root;
    }

Dynamic Programming

10 Regular Expression Matching

https://leetcode-cn.com/problems/regular-expression-matching/
在这里插入图片描述

private Map<String, Boolean> memo = new HashMap<>();

    public boolean isMatch(String s, String p) {
        return dp(s, 0, p, 0);
    }

    private boolean dp(String s, int i, String p, int j) {
        if (i == s.length()) {
            if ((p.length() - j) % 2 == 1) {
                return false;
            }
            for (; j + 1 < p.length(); j += 2) {
                if (p.charAt(j + 1) != '*') {
                    return false;
                }
            }
            return true;
        }

        if (j == p.length()) {
            return i == s.length();
        }
        char[] charS = s.toCharArray();
        char[] charP = p.toCharArray();
        String key = i + "," + j;
        if (memo.containsKey(key)) return memo.get(key);
        boolean res;
        if (charS[i] == charP[j] || charP[j] == '.') {
            if (j + 1 < p.length() && charP[j + 1] == '*') {
                res = dp(s, i, p, j + 2) || dp(s, i + 1, p, j);
            } else {
                res = dp(s, i + 1, p, j + 1);
            }
        } else {
            if (j + 1 < p.length() && charP[j + 1] == '*') {
                res = dp(s, i, p, j + 2);
            } else {
                res = false;
            }
        }
        memo.put(key, res);
        return res;
    }

53 Maximum Subarray

    public int maxSubArray(int[] nums) {
        if (nums.length == 0) return 0;
        int[] dp = new int[nums.length];
        dp[0] = nums[0];
        int res = Integer.MIN_VALUE;
        for (int i = 1; i < nums.length; i++) {
            if (dp[i - 1] > 0) {
                dp[i] = dp[i - 1] + nums[i];
            } else {
                dp[i] = nums[i];
            }
            res = Math.max(res, dp[i]);
        }
        return res;
    }
    
    //优化一下,可以不需要dp数组
     public int maxSubArray2(int[] nums) {
        if (nums.length == 0) return 0;
        int dpNum = nums[0];
        int res = dpNum;
        for (int i = 1; i < nums.length; i++) {
            if (dpNum > 0) {
                dpNum += nums[i];
            } else {
                dpNum = nums[i];
            }
            res = Math.max(res, dpNum);
        }
        return res;
    }

55 Jump Game

https://leetcode-cn.com/problems/jump-game/
在这里插入图片描述

 public boolean canJump(int[] nums) {
        if(nums==null)return true;
        if(nums[0]==0&&nums.length>1)return false;
        boolean flag=false;
        for(int i = nums.length-2;i>0;i--){
            if(nums[i]==0){
                flag=false;
                int step=0;
                while(i>0){
                    step++;
                    i--;
                    if(nums[i]>step){
                        flag=true;
                        break;
                    }
                }
                if(!flag)return false;
            }
        }
        return true;
    }

62 Unique Paths

https://leetcode-cn.com/problems/unique-paths/
62、63、64 都属于同一种类型的,可以一起做一下
在这里插入图片描述

    public int uniquePaths(int m, int n) {
        int dp[][]=new int [m][n];
        for(int i =0;i<m;i++){
            dp[i][0]=1;
        }
        for(int i =0;i<n;i++){
            dp[0][i]=1;
        }
         for(int i =1;i<m;i++){
             for(int j =1;j<n;j++){
                 dp[i][j]=dp[i-1][j]+dp[i][j-1];
             }
         }
         return dp[m-1][n-1];
    }

63 Unique Paths II

https://leetcode-cn.com/problems/unique-paths-ii/
在这里插入图片描述

在这里插入图片描述

 public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        if(obstacleGrid==null)return 0;
        int row =obstacleGrid.length;
        int column =obstacleGrid[0].length;
        int[][]dp = new int[row][column];
        if(obstacleGrid[0][0]==1)return 0;
        dp[0][0]=1;
         for(int i =1;i<row;i++){
            if(obstacleGrid[i][0]!=1)dp[i][0]=dp[i-1][0];
        }
        for(int i =1;i<column;i++){
            if(obstacleGrid[0][i]!=1)dp[0][i]=dp[0][i-1];
        }
          for(int i =1;i<row;i++){
              for(int j =1;j<column;j++){
                    if(obstacleGrid[i][j]!=1)dp[i][j]=dp[i-1][j]+dp[i][j-1];
              }
          }
          return dp[row-1][column-1];
    }

64 Minimum Path Sum

https://leetcode-cn.com/problems/minimum-path-sum/
在这里插入图片描述

  public int minPathSum(int[][] grid) {
        if(grid==null)return 0;
        int row=grid.length;
        int column=grid[0].length;
         for(int i =1;i<row;i++){
            grid[i][0]+=grid[i-1][0];
        }
        for(int i =1;i<column;i++){
           grid[0][i]+=grid[0][i-1];
        }
        for(int i =1;i<row;i++){
              for(int j =1;j<column;j++){
                   grid[i][j]+=Math.min(grid[i-1][j],grid[i][j-1]);
              }
          }
          return grid[row-1][column-1];
    }

70 Climbing Stairs

https://leetcode-cn.com/problems/climbing-stairs/
在这里插入图片描述

    public int climbStairs(int n){
        if(n==0)return 0;
        if(n==1)return 1;
        int dp[] = new int[n+1];
        dp[1]=1;
        dp[2]=2;
        for(int i = 3;i<=n;i++){
           dp[i]=dp[i-1]+dp[i-2]; 
        }
        return dp[n];
    }

91 Decode Ways

https://leetcode-cn.com/problems/decode-ways/
在这里插入图片描述
这题用dp,主要是得理解切入点在判断一个字符和两个字符上。

 public int numDecodings(String s) {
        int length = s.length();
        int[] dp = new int[length + 1];
        dp[0]=1;
        for (int i = 1; i <= length; i++) {
            if(s.charAt(i-1)!='0'){
                dp[i]+=dp[i-1];
            }
            if(i>1&&s.charAt(i-2)!='0'&&((s.charAt(i-2)-'0')*10+(s.charAt(i-1)-'0'))<=26){
                dp[i]+=dp[i-2];
            }
        }
        return dp[length];
    }

97 Interleaving String

https://leetcode-cn.com/problems/interleaving-string/
在这里插入图片描述

  public boolean isInterleave(String s1, String s2, String s3) {
        //不能这么判断
        //  if (s1.equals("")) return s2.equals(s3);
        // if (s2.equals("")) return s1.equals(s3);
        int n = s1.length(), m = s2.length(), t = s3.length();
        if (n + m != t) {
            return false;
        }
        boolean[][] dp = new boolean[n + 1][m + 1];

        dp[0][0] = true;
        for (int i = 0; i <= n; ++i) {
            for (int j = 0; j <= m; ++j) {
                int p = i + j - 1;
                if (i > 0) {
                    dp[i][j] = dp[i][j] || (dp[i - 1][j] && s1.charAt(i - 1) == s3.charAt(p));
                }
                if (j > 0) {
                    dp[i][j] = dp[i][j] || (dp[i][j - 1] && s2.charAt(j - 1) == s3.charAt(p));
                }
            }
        }
        return dp[n][m];
    }

120 Triangle

https://leetcode-cn.com/problems/triangle/
在这里插入图片描述

 public int minimumTotal(List<List<Integer>> triangle) {
        int[][] dp = new int[triangle.size()][triangle.get(triangle.size() - 1).size()];
        int res = Integer.MAX_VALUE;
        dp[0][0] = triangle.get(0).get(0);
        for (int i = 1; i < triangle.size(); i++) {
            for (int i1 = 0; i1 < triangle.get(i).size(); i1++) {
                dp[i][i1]=triangle.get(i).get(i1);
                if (i1 == triangle.get(i).size() - 1) {
                    dp[i][i1] += dp[i - 1][i1 - 1]+triangle.get(i).get(i1);
                    continue;
                }
                if (i1 == 0) {
                    dp[i][i1] += (dp[i - 1][i1] + triangle.get(i).get(0));
                } else {
                    dp[i][i1] += Math.min(dp[i - 1][i1], dp[i - 1][i1 - 1]) + triangle.get(i).get(i1);
                }
            }
        }
        for (int n = 0; n < dp.length; n++) {
            res = Math.min(dp[dp.length - 1][n], res);
        }
        return res;
    }

121 Best Time To Buy And Sell Stock

https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/
在这里插入图片描述

    public int maxProfit(int[] prices) {
	 if (prices.length < 1) {
            return 0;
        }
        int min = prices[0],dpValue=0;
        for (int i = 0; i < prices.length; i++) {
            if (prices[i] - min > dpValue) {
                dpValue=prices[i] - min;
            }
            if(prices[i]<min){
                min=prices[i];
            }
        }
        return dpValue;
    }

122 Best Time To Buy And Sell Stock II

https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/
在这里插入图片描述
dp和贪心算法均可。dp需要想到状态转移方程,贪心需要想到每天的股票价格并不影响。

 public int maxProfit(int[] prices) {
        if (prices.length<=1)return 0;
        int[][] dp   = new int[prices.length][2];
        dp[0][0]=0;
        dp[0][1]=-prices[0];
        for (int i = 1; i <prices.length ; i++) {
            dp[i][0]=Math.max(dp[i-1][1]+prices[i],dp[i-1][0]);
            dp[i][1]=Math.max(dp[i-1][0]-prices[i],dp[i-1][1]);
        }
        return dp[prices.length-1][0];
    }

   public int maxProfit(int[] prices) {
	   if (prices.length<=1)return 0;
        int res = 0;
        for (int i = 1; i <prices.length; i++) {
            res+=Math.max(0,prices[i]-prices[i-1]);
        }
        return res;
    }

152 Maximum Product Subarray

https://leetcode-cn.com/problems/maximum-product-subarray/
在这里插入图片描述
这题和53题相似,就是要注意复数乘以复数的情况,所以需要保存之前的最大最小值。

   public int maxProduct(int[] nums) {
        if(nums==null)return 0;
        int maxP=nums[0];
        int minP=nums[0];
        int res = nums[0];
        for(int i =1;i<nums.length;i++){
          int tempMax=maxP,tempMin=minP;
           maxP=Math.max(Math.max(nums[i],tempMax*nums[i]),tempMin*nums[i]);
           minP=Math.min(Math.min(nums[i],tempMin*nums[i]),tempMax*nums[i]);
           res=Math.max(maxP,res);
        }
        return res;
    }

198 House Robber

https://leetcode-cn.com/problems/house-robber/
在这里插入图片描述

 // public int rob(int[] nums) {
    //   if(nums==null)return 0;
    //   if(nums.length==1)return nums[0];
    //   int dp[]=new int [nums.length];
    //   dp[0]=nums[0];
    //   dp[1]=nums[1];
    //   for(int i =2;i<nums.length;i++){
    //       int max= 0;
    //       for(int j=0;j<i-1;j++){
    //           dp[i]=max=Math.max(dp[j]+nums[i],max);
    //       }
    //   }
    //   int max=0;
    //       for(int i =0;i<nums.length;i++){
    //           max=Math.max(max,dp[i]);
    //       }
    //   return max;
    // }

    public int rob(int[] nums) {
         if(nums==null)return 0;
      if(nums.length==1)return nums[0];
      int dp[]=new int[nums.length];
      dp[0]=nums[0];
      dp[1]=Math.max(nums[0],nums[1]);
      for(int i =2;i<nums.length;i++){
          dp[i]=Math.max(dp[i-1],dp[i-2]+nums[i]);
      }
      return dp[nums.length-1];
    }
    

213 House Robber II

https://leetcode-cn.com/problems/house-robber-ii/
在这里插入图片描述

  public int rob(int[] nums) {
         if(nums==null)return 0;
      if(nums.length==1)return nums[0];
      return Math.max(robArr(nums,0,nums.length-1),robArr(nums,1,nums.length));
    
    }

    public int robArr(int [] nums,int start, int end){
        int[] a = new int[end-start];
        int sTemp=start;
        for(int i =0;i<end-start;i++){
            a[i]=nums[sTemp];
            sTemp++;
        }
        return rob1(a);
    }

     public int rob1(int[] nums) {
         if(nums==null)return 0;
      if(nums.length==1)return nums[0];
      int dp[]=new int[nums.length];
      dp[0]=nums[0];
      dp[1]=Math.max(nums[0],nums[1]);
      for(int i =2;i<nums.length;i++){
          dp[i]=Math.max(dp[i-1],dp[i-2]+nums[i]);
      }
      return dp[nums.length-1];
    }

300 Longest Increasing Subsequence

https://leetcode-cn.com/problems/longest-increasing-subsequence/
在这里插入图片描述

public int lengthOfLIS(int[] nums) {
        if (nums.length < 1) return 0;
        if (nums.length == 1) return 1;
        int[] dp = new int[nums.length];
        Arrays.fill(dp, 1);
        for (int i = 0; i < nums.length; i++) {
            for (int j = 0; j < i; j++) {
                if (nums[i] > nums[j]) {
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                }
            }
        }
        int res = 0;
        for (int i = 0; i < nums.length; i++) {
            res = Math.max(res, dp[i]);
        }
        return res;
    }

312 Burst Balloons

https://leetcode-cn.com/problems/burst-balloons/
在这里插入图片描述
dp[i][j]:戳破第i个气球和第j个气球之间的所有气球得到的最大分数

  public int maxCoins(int[] nums) {
          if(nums==null)return 0;
        int point[] = new int[nums.length+2];
        point[0]=1;
        point[nums.length+1]=1;
        for (int i = 1; i <=nums.length ;i++) {
            point[i]=nums[i-1];
        }
        
        int dp[][] = new int[nums.length+2][nums.length+2];

        for (int i = point.length-2; i >=0 ; i--) {
            for (int j = i+1; j <point.length ; j++) {
                for (int k = i+1; k <j ; k++) {
                    dp[i][j]=Math.max(dp[i][j],dp[i][k]+dp[k][j]+point[i]*point[k]*point[j]);
                }
            }
        }
        return dp[0][point.length-1];
    }

322 Coin Change

https://leetcode-cn.com/problems/coin-change/
在这里插入图片描述

 public int coinChange(int[] coins, int amount) {
        if (coins.length == 0) return -1;
        int[] dp = new int[amount + 1];
        Arrays.fill(dp, amount + 1);
        dp[0] = 0;
        for (int i = 1; i <= amount; ++i) {
            for (int j = 0; j < coins.length; ++j) {
                if (i >= coins[j]) {
                    dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1);
                }
            }
        }
        return dp[amount] == amount + 1 ? -1 : dp[amount];
    }

354 Russian Doll Envelopes

https://leetcode-cn.com/problems/russian-doll-envelopes/
在这里插入图片描述

 public int maxEnvelopes(int[][] envelopes) {
        Arrays.sort(envelopes, new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                if(o1[0]!=o2[0])return o1[0]-o2[0];
                if(o1[1]>=o2[1]) return -1;
                else return 1;
            }
        });
        int[] ints = new int[envelopes.length];
        for (int i = 0; i < envelopes.length; i++) {
            ints[i]=envelopes[i][1];
        }
        return findLengthOfLCIS(ints);
    }

    private int findLengthOfLCIS(int[] nums) {
            if(nums.length<1)return 0;
            if(nums.length==1)return 1;
            int [] dp = new int[nums.length];
            Arrays.fill(dp,1);
            for(int i = 0;i<nums.length;i++){
                for(int j=0;j<i;j++){
                    if(nums[i]>nums[j]){
                        dp[i]=Math.max(dp[i],dp[j]+1);
                    }
                }
            }
            int res = 0;
            for(int i = 0;i<nums.length;i++){
                res = Math.max(res,dp[i]);
            }
            return res;
    }

516 Longest Palindromic Subsequence

https://leetcode-cn.com/problems/longest-palindromic-subsequence/
在这里插入图片描述

 //普通二位dp
    public int longestPalindromeSubseq(String s) {
        if(s.length()==0)return 0;
        char[] chars = s.toCharArray();
        int [][]dp = new int[chars.length][chars.length];
        for (int i = 0; i < chars.length; i++) {
            dp[i][i]=1;
        }
        for (int i = chars.length-2; i>=0 ; i--) {
            for (int j = i+1; j <chars.length ; j++) {
                if(chars[i]==chars[j])dp[i][j]=dp[i+1][j-1]+2;
                else dp[i][j]=Math.max(dp[i][j-1],dp[i+1][j]);
            }
        }
        return dp[0][chars.length-1];
    }
    //普通一维dp
    public int longestPalindromeSubseq2(String s) {
        if(s.length()==0)return 0;
        char[] chars = s.toCharArray();
        int []dp = new int[chars.length];
        for (int i = 0; i < chars.length; i++) {
            dp[i]=1;
        }
        for (int i = chars.length-2; i>=0 ; i--) {
            int pre=0;
            for (int j = i+1; j <chars.length ; j++) {
                int temp = dp[j];
                if(chars[i]==chars[j])dp[j]=pre+2;
                else dp[j]=Math.max(dp[j-1],dp[j]);
                pre =temp;
            }
        }
        return dp[chars.length-1];
    }

887 Super Egg Drop (待优化)

https://leetcode-cn.com/problems/super-egg-drop/
在这里插入图片描述

	//	不能ac
   Map<String,Integer>memo = new HashMap<>();
    
    public int superEggDrop(int k, int n) {
        return dp(k,n);
    }

    private int dp(int k, int n) {
        if(k==1)return n;
        if(n==0)return 0;
        
        if(memo.containsKey(k+","+n))return memo.get(k+","+n);
        int res = Integer.MAX_VALUE;
        for (int i = 1; i <= n; i++) {
            res=Math.min(res,Math.max(dp(k-1,i-1),dp(k,n-i))+1);
        }
        memo.put(k+","+n,res);
        return res;
    }
	

	//二分搜索减枝
	Map<String,Integer>memo = new HashMap<>();
    
    public int superEggDrop(int k, int n) {
        return dp(k,n);
    }

    private int dp(int k, int n) {
        if(k==1)return n;
        if(n==0)return 0;
        
        if(memo.containsKey(k+","+n))return memo.get(k+","+n);
        int res = Integer.MAX_VALUE;
        int lo=1;
        int high=n;
        while(lo<=high){
           int mid=(lo+high)>>1;
             int broken = dp(k-1,mid-1);
             int unBroken = dp(k,n-mid);
             if(broken>unBroken){
                 high=mid-1;
                 res=Math.min(res,broken+1);
             }else{
                 lo=mid+1;
                 res=Math.min(res,unBroken+1);
             }
        }
        memo.put(k+","+n,res);
        return res;
    }

1312 Minimum Insertion Steps To Make A String Palindrome

https://leetcode-cn.com/problems/minimum-insertion-steps-to-make-a-string-palindrome/
在这里插入图片描述

    public int minInsertions(String s) {
 if (s == null || s.length() == 0) {
            return 0;
        }

        char[] chars = s.toCharArray();
        int[] dp = new int[chars.length];
        for (int i = dp.length - 2; i >= 0; i--) {
            int pre =0;
            for (int j = i + 1; j < chars.length; j++) {
                int temp=dp[j];
                if (chars[i] == chars[j]) dp[j] = pre;
                else {
                    dp[j]=Math.min(dp[j],dp[j-1])+1;
                }
                pre =temp;
            }
        }
        return dp[chars.length-1];
    }

Offer 20 回文子字符串的个数(待优化)

https://leetcode-cn.com/problems/a7VOhD/
在这里插入图片描述

//待优化
  public int countSubstrings(String s) {
       if (s == null || s.length() == 0) return 0;
        char[] chars = s.toCharArray();
        int[] dp = new int[chars.length];
        int j = 0;
        for (int i = 0; i < chars.length; i++) {
            dp[i] = 1;
        }
        int count = chars.length;
        for (int i = chars.length - 2; i >= 0; i--) {
            int pre = 0;
            for (j = i + 1; j < chars.length; j++) {
                int temp = dp[j];
                if (j - i == 1 && chars[i] == chars[j]) {
                    dp[j] = 1;
                    count += 1;
                } else if (chars[i] == chars[j] && pre >= 1) {
                    dp[j] = 1;
                    count += 1;
                }else {
                    dp[j]=0;
                }
                pre = temp;
            }
        }
        return count;
    }

DFS

17 Letter Combinations Of A Phone Number

https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/
在这里插入图片描述

   public List<String> letterCombinations(String digits) {
        List<String> lists  = new ArrayList<>();
        if (digits.length()<1)return lists;
        Map<Character,String> map = new HashMap<>();
        map.put('2', "abc");
        map.put('3', "def");
        map.put('4', "ghi");
        map.put('5', "jkl");
        map.put('6', "mno");
        map.put('7', "pqrs");
        map.put('8', "tuv");
        map.put('9', "wxyz");
        dfs(digits,0,"",lists,map);
        return lists;
    }

    private void dfs(String digits, int start, String s, List<String> lists, Map<Character, String> map) {
        if(start==digits.length()){
            lists.add(s);
            return;
        }
        char c = digits.charAt(start);
        char[] tree = map.get(c).toCharArray();
        for (int i = 0; i < tree.length; i++) {
            dfs(digits,start+1, s+tree[i], lists,map);
        }
        return;
    }

110 Balanced Binary Tree

https://leetcode-cn.com/problems/balanced-binary-tree/
在这里插入图片描述

//法一:自顶向下计算长度
    public boolean isBalanced(TreeNode root) {
        if (root==null)return true;
        return Math.abs(getCount(root.left,0)-getCount(root.right,0))<=1 ;
    }

    public  int  getCount(TreeNode root,int count){
        if(root==null) return count;
        count++;
        return Math.max(getCount(root.left,count),getCount(root.right,count));
    }

//法二:自低向上计算长度
public boolean isBalanced(TreeNode root) {
        if (root == null) return true;
        return height(root) >= 0;
    }

    private int height(TreeNode root) {
        if (root == null) return 0;
        int leftHeight =height(root.left);
        int rightHeight =height(root.right);
        if(leftHeight==-1||rightHeight==-1||Math.abs(leftHeight-rightHeight)>1){
            return -1;
        }
        return Math.max(leftHeight,rightHeight)+1;
    }

Binary Search

*29 Divide Two Integers

https://leetcode-cn.com/problems/divide-two-integers/
在这里插入图片描述

  public int divide(int dividend, int divisor) {
        // 考虑被除数为最小值的情况
        if (dividend == Integer.MIN_VALUE) {
            if (divisor == 1) {
                return Integer.MIN_VALUE;
            }
            if (divisor == -1) {
                return Integer.MAX_VALUE;
            }
        }
        // 考虑除数为最小值的情况
        if (divisor == Integer.MIN_VALUE) {
            return dividend == Integer.MIN_VALUE ? 1 : 0;
        }
        // 考虑被除数为 0 的情况
        if (dividend == 0) {
            return 0;
        }
        
        // 一般情况,使用二分查找
        // 将所有的正数取相反数,这样就只需要考虑一种情况
        boolean rev = false;
        if (dividend > 0) {
            dividend = -dividend;
            rev = !rev;
        }
        if (divisor > 0) {
            divisor = -divisor;
            rev = !rev;
        }
        
        int left = 1, right = Integer.MAX_VALUE, ans = 0;
        while (left <= right) {
            // 注意溢出,并且不能使用除法
            int mid = left + ((right - left) >> 1);
            boolean check = quickAdd(divisor, mid, dividend);
            if (check) {
                ans = mid;
                // 注意溢出
                if (mid == Integer.MAX_VALUE) {
                    break;
                }
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }

        return rev ? -ans : ans;
    }

    // 快速乘
    //用来判断z*y是否已经超过了x
    public boolean quickAdd(int y, int z, int x) {
        // x 和 y 是负数,z 是正数
        int result = 0, add = y;
        while (z != 0) {
        //z是单数的情况
            if ((z & 1) != 0) {
                // 需要保证 result + add >= x
                if (result < x - add) {
                    return false;
                }
                result += add;
            }
            if (z != 1) {
                // 需要保证 add + add >= x
                if (add < x - add) {
                    return false;
                }
                //应为后面对z取一半,所以需要双倍加
                add += add;
            }
            // 不能使用除法
            z >>= 1;
        }
        return true;
    }

Back Track

46 Permutations

https://leetcode-cn.com/problems/permutations/
在这里插入图片描述

 private  List<List<Integer>>res =new ArrayList<>();
    public List<List<Integer>> permute(int[] nums) {
        if(nums.length==0){
            return new ArrayList<>();
        }
        List<Integer> track = new ArrayList<>();
        backTrack(nums,track);
        return res;
    }

    private void backTrack(int[] nums, List<Integer> track) {
        if(nums.length==track.size()){
            res.add(new ArrayList<>(track));
            return;
        }
        for (int i = 0; i < nums.length; i++) {
             if (track.contains((Integer)nums[i])) {
                continue;
            }
            track.add(nums[i]);
            backTrack(nums,track);
            track.remove((Integer)nums[i]);
        }
    }

51 N Queens

https://leetcode-cn.com/problems/n-queens/
在这里插入图片描述

class Solution {
    public List<List<String>> solveNQueens(int n) {
        List<List<String>> solutions = new ArrayList<List<String>>();
        //由于java操作链表比较麻烦,这里queen用来记录i行的Q元素的列标
        int[] queens = new int[n];
        Arrays.fill(queens, -1);
        //用来记录行元素是否含有Q
        Set<Integer> columns = new HashSet<Integer>();
		//用来记录该元素左上角元素是否含有Q
        Set<Integer> diagonals1 = new HashSet<Integer>();
        //用来记录该元素右上角元素是否含有Q
        Set<Integer> diagonals2 = new HashSet<Integer>();
        backtrack(solutions, queens, n, 0, columns, diagonals1, diagonals2);
        return solutions;
    }

    public void backtrack(List<List<String>> solutions, int[] queens, int n, int row, Set<Integer> columns, Set<Integer> diagonals1, Set<Integer> diagonals2) {
        if (row == n) {
            List<String> board = generateBoard(queens, n);
            solutions.add(board);
        } else {
            for (int i = 0; i < n; i++) {
            //这三个判断太妙了
                if (columns.contains(i)) {
                    continue;
                }
                int diagonal1 = row - i;
                if (diagonals1.contains(diagonal1)) {
                    continue;
                }
                int diagonal2 = row + i;
                if (diagonals2.contains(diagonal2)) {
                    continue;
                }
                //添加
                queens[row] = i;
                columns.add(i);
                diagonals1.add(diagonal1);
                diagonals2.add(diagonal2);
                //继续下一行
                backtrack(solutions, queens, n, row + 1, columns, diagonals1, diagonals2);
                //复原
                queens[row] = -1;
                columns.remove(i);
                diagonals1.remove(diagonal1);
                diagonals2.remove(diagonal2);
            }
        }
    }

//生成整个棋盘
    public List<String> generateBoard(int[] queens, int n) {
        List<String> board = new ArrayList<String>();
        for (int i = 0; i < n; i++) {
            char[] row = new char[n];
            Arrays.fill(row, '.');
            row[queens[i]] = 'Q';
            board.add(new String(row));
        }
        return board;
    }
}

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/n-queens/solution/nhuang-hou-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

BFS

111 Minimum Depth Of Binary Tree

https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/
在这里插入图片描述
这题标准的BFS,也可以用DFS。

//BFS
    public int minDepth(TreeNode root) {
     if(root==null)return 0;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        int num=1;
        while (!queue.isEmpty()){
            int sz =queue.size();
            for (int i = 0; i < sz; i++) {
                TreeNode cur  =queue.poll();
                if(cur.left==null&&cur.right==null)return num;
                if(cur.left!=null){
                    queue.add(cur.left);
                }
                if(cur.right!=null){
                    queue.add(cur.right);
                }
            }
            num++;
        }
        return num;
    }

 //  public int minDepth(TreeNode root) {
    //       if (root == null) return 0;
    //     if (root.left == null && root.right == null) return 1;
    //     int min = Integer.MAX_VALUE;

    //     int left=Integer.MAX_VALUE;
    //     if(root.left!=null){
    //         left = minDepth(root.left);
    //     }
    //     int right=Integer.MAX_VALUE;
    //     if(root.right!=null) {
    //         right = Math.min(minDepth(root.right),min);
    //     }
    //     return Math.min(left, right) + 1;
    // }

剑指OFFER II 109

https://leetcode-cn.com/problems/zlDJc7/
在这里插入图片描述

//会了BFS框架,整道题就比较好理解
public int openLock(String[] deadends, String target) {
        Set<String> dead = new HashSet<>();
        for (String deadend : deadends) {
            dead.add(deadend);
        }
        Queue<String> queue = new LinkedList<>();
        Set<String> visited = new HashSet<>();
        int step = 0;
        queue.offer("0000");
        visited.add("0000");
        while (!queue.isEmpty()){
            int size = queue.size();
      
            for (int i = 0; i < size; i++) {
                String cur = queue.poll();
                if (dead.contains(cur))
                 continue;
                if (cur.equals(target)) {
                    return step;
                }
                for (int j = 0; j < 4; j++) {  
                    String up =upOne(cur, j);
                    if(!visited.contains(up)){
                        queue.offer(up);
                        visited.add(up);
                    }
                    String down =downOne(cur, j);
                    if(!visited.contains(down)){
                        queue.offer(down);
                        visited.add(down);
                    }
                }
            }
             step++;
        }
        return -1;
    }

//可以先从这开始写
    String upOne(String target, int targetNum) {
        char[] chars = target.toCharArray();
            if (chars[targetNum] == '9') {
                chars[targetNum] = '0';
            } else {
                chars[targetNum] += 1;
            }
        return new String(chars);
    }

    String downOne(String target, int targetNum) {
        char[] chars = target.toCharArray();
            if (chars[targetNum] == '0') {
                chars[targetNum] = '9';
            } else {
                chars[targetNum] -= 1;
            }
        return new String(chars);
    }

Two Pointers

Offer II 22 链表中环的入口节点

https://leetcode-cn.com/problems/c32eOV/
在这里插入图片描述

    public ListNode detectCycle(ListNode head) {
        ListNode fast=head,slow=head;
        while (fast != null && fast.next != null) {
            fast=fast.next.next;
            slow=slow.next;
            if(slow==fast)break;
        }
        //注意这里需要判断一下
        if(fast==null||fast.next==null)return null;
        slow=head;
        while (slow != fast) {
            slow=slow.next;
            fast=fast.next;
        }
        return slow;
    }

Sliding Window

209 Minimum Size Subarray Sum

https://leetcode-cn.com/problems/minimum-size-subarray-sum/
在这里插入图片描述

public int minSubArrayLen(int target, int[] nums) {
        if (nums.length == 0) return 0;
        int start = 0, end = 0;
        int sub = 0;
        int res = Integer.MAX_VALUE;
        while (end < nums.length) {
            sub += nums[end];
            end++;
            while (sub >= target) {
                sub -= nums[start];
                res = Math.min(res, end-start);
                start++;
            }
            
        }
        return res==Integer.MAX_VALUE?0:res;
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

L-->R

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值