做的力扣上的题目的代码,暂存在这里

```java
    //90. 子集 II
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        List<Integer> path = new ArrayList<>();
        Arrays.sort(nums);
        boolean[] vis = new boolean[nums.length + 1];
        dfs(nums, 0, vis, res, path);
        return res;
    }

    public void dfs(int[] nums, int cur, boolean[] vis, List<List<Integer>> res, List<Integer> path) {
//        res.add(new ArrayList<>(path));
//        for(int i=cur; i<nums.length;i++){
//            if(i!=cur&&nums[i]==nums[i-1]){
//                continue;
//            }
//            path.add(nums[i]);
//            dfs(nums,i+1,vis,res,path);
//            path.remove(path.size()-1);
//        }

        if (cur == nums.length) {
            res.add(new ArrayList<>(path));
            System.out.println(path);
            return;
        }
        path.add(nums[cur]);
        vis[cur] = true;
        dfs(nums, cur + 1, vis, res, path);
        vis[cur] = false;
        path.remove(path.size() - 1);
        dfs(nums, cur + 1, vis, res, path);
    }

    //89. 格雷编码
    public List<Integer> grayCode(int n) {
        List<Integer> list = new ArrayList<>();
        list.add(0);
        for (int i = 1; i <= n; i++) {
            int m = list.size();
            for (int j = m - 1; j >= 0; j--) {
                list.add(list.get(j) | (1 << (i - 1)));
            }

        }

        return list;
    }

    //86. 分隔链表
    public ListNode partition(ListNode head, int x) {
        ListNode small = new ListNode(0);
        ListNode large = new ListNode(0);
        ListNode sh = small;
        ListNode lh = large;
        while (head != null) {
            if (head.val < x) {
                small.next = head;
                small = small.next;
            } else {
                large.next = head;
                large = large.next;
            }
            head = head.next;
        }
        large.next = null;
        small.next = lh.next;
        return sh.next;
    }

    //81、删除排序链表中的重复元素 I
    public ListNode deleteDuplicates(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode pre = new ListNode(0, head);
        ListNode cur = pre;
        while (cur.next != null && cur.next.next != null) {
            if (cur.next.val == cur.next.next.val) {
                int temp = cur.next.val;
                cur = cur.next;
                while (cur.next != null && cur.next.val == temp) {
                    cur.next = cur.next.next;
                }

            } else {
                cur = cur.next;
            }
        }
        return pre.next;
    }

    //82. 删除排序链表中的重复元素 II
    public ListNode deleteDuplicates82(ListNode head) {
        if (head == null || head.next == null)
            return head;
        ListNode pre = new ListNode();
        pre.next = head;
        ListNode cur = pre;
        while (cur.next != null && cur.next.next != null) {
            if (cur.next.val != cur.next.next.val) {
                cur = cur.next;
            } else {
                int x = cur.next.val;
                while (cur.next != null && cur.next.val == x) {
                    cur.next = cur.next.next;
                }
            }
        }
        return pre.next;
    }

    //81. 搜索旋转排序数组 II
    public boolean search(int[] nums, int target) {
        int l = 0, r = nums.length - 1;
        while (l <= r) {
            int mid = (l + r) / 2;
            if (nums[mid] == target)
                return true;
            if (nums[l] == nums[mid] && nums[mid] == nums[r]) {
                l++;
                r--;
            } else if (nums[l] <= nums[mid]) {
                if (nums[l] <= target && target <= nums[mid]) {
                    r = mid - 1;
                } else {
                    l = mid + 1;
                }
            } else {
                if (nums[mid] > target && target <= nums[nums.length - 1]) {
                    l = mid + 1;
                } else {
                    r = mid - 1;
                }
            }
        }
        return false;
    }

    //80. 删除有序数组中的重复项 II
    public int removeDuplicates(int[] nums) {
        int n = nums.length;
        if (n <= 2) {
            return n;
        }
        int slow = 2, fast = 2;
        while (fast < n) {
            if (nums[slow - 2] != nums[fast]) {
                nums[slow] = nums[fast];
                ++slow;
            }
            ++fast;
        }
        return slow;
    }

    //79、单词搜索
    public boolean exist(char[][] board, String word) {
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                boolean[][] vis = new boolean[board.length][board[0].length];
                if (dfs(board, i, j, word, 0, vis)) {
                    return true;
                }
            }
        }
        return false;
    }

    public boolean dfs(char[][] board, int x, int y, String word, int k, boolean[][] vis) {
        if (x < 0 || y < 0 || x >= board.length || y >= board[0].length) {
            return false;
        }
        if (!vis[x][y]) {
            if (board[x][y] != word.charAt(k))
                return false;
            else if (k == word.length() - 1) {
                System.out.println(k);
                return true;
            }

            vis[x][y] = true;
            boolean right = dfs(board, x + 1, y, word, k + 1, vis);
            boolean left = dfs(board, x - 1, y, word, k + 1, vis);
            boolean up = dfs(board, x, y + 1, word, k + 1, vis);
            boolean down = dfs(board, x, y - 1, word, k + 1, vis);
            if (right || left || up || down) {
                return true;
            }
            vis[x][y] = false;
        }
        return false;
    }

    //78、子集
    LinkedHashMap<List<Integer>, Integer> ans = new LinkedHashMap<>();
    List<Integer> t = new ArrayList<>();

    public List<List<Integer>> subsets(int[] nums) {
        boolean[] vis = new boolean[nums.length + 1];
        dfs(0, nums, vis);
        List<List<Integer>> list = new ArrayList<>();
        for (List<Integer> m : ans.keySet()) {
            list.add(m);
        }
        return list;
    }

    public void dfs(int cur, int[] nums, boolean[] vis) {
        if (cur == nums.length) {
            ans.put(new ArrayList<Integer>(t), 1);
            return;
        }
        for (int i = 0; i < 3; i++) {
            if (vis[nums[i]])
                continue;
            vis[nums[i]] = true;
            t.add(nums[i]);
            dfs(cur + 1, nums, vis);
            vis[nums[i]] = false;
            t.remove(t.size() - 1);
            dfs(cur + 1, nums, vis);
        }


    }

    //77、组合
    public List<List<Integer>> combine(int n, int k) {
        List<List<Integer>> res = new ArrayList<>();
        List<Integer> list = new ArrayList<>();
        boolean[] vis = new boolean[n + 1];
        backtrace77(n, k, 1, res, list, vis);
        return res;
    }

    public void backtrace77(int n, int k, int depth, List<List<Integer>> res, List<Integer> path, boolean[] vis) {
        if (path.size() == k) {
            res.add(new ArrayList<>(path));
            return;
        }
        for (int i = depth; i <= n; i++) {
            if (vis[i]) {
                continue;
            }
            vis[i] = true;
            path.add(i);
            backtrace77(n, k, i + 1, res, path, vis);
            path.remove(path.size() - 1);
            vis[i] = false;
        }
    }

    //75、颜色分类
    //双指针
    public void sortColors(int[] nums) {
        int p0 = 0;
        int p1 = 0;
        int len = nums.length;
        for (int i = 0; i < len; i++) {
            if (nums[i] == 1) {
                int temp = nums[p1];
                nums[p1] = 1;
                nums[i] = temp;
                p1++;
            } else if (nums[i] == 0) {
                int temp = nums[p0];
                nums[p0] = 0;
                nums[i] = temp;
                if (p0 < p1) {
                    temp = nums[p1];
                    nums[p1] = nums[i];
                    nums[i] = temp;
                }
                p0++;
                p1++;

            }
        }
    }
    //单指针
    public void sortColors_1(int[] nums) {
        int len = nums.length;
        int ptr = 0;
        for (int i = 0; i < len; i++) {
            if (nums[i] == 0) {
                int temp = nums[ptr];
                nums[ptr] = 0;
                nums[i] = temp;
                ptr++;
            }
        }
        for (int i = ptr; i < len; i++) {
            if (nums[i] == 1) {
                int temp = nums[ptr];
                nums[ptr] = 1;
                nums[i] = temp;
                ptr++;
            }
        }
    }

    //74. 搜索二维矩阵
    public boolean searchMatrix(int[][] matrix, int target) {
        int r = 0;
        int mid = 0;
        int posRow = binarySearchRow(target, matrix);
        if (posRow < 0) {
            return false;
        }
        return binarySearchCol(target, matrix, posRow);
    }

    int binarySearchRow(int target, int[][] nums) {
        int l = -1;
        int r = nums.length - 1;
        while (l < r) {
            int mid = (r - l + 1) / 2 + l;
            if (nums[mid][0] == target) {
                return mid;
            }
            if (nums[mid][0] > target) {
                r = mid - 1;
            }
            if (nums[mid][0] < target) {
                l = mid;
            }
        }
        return l;
    }

    boolean binarySearchCol(int target, int[][] nums, int posRow) {
        int l = 0;
        int r = nums[0].length - 1;
        while (l <= r) {
            int mid = (l + r) / 2;
            if (nums[posRow][mid] == target)
                return true;
            if (nums[posRow][mid] > target) {
                r = mid - 1;
            }
            if (nums[posRow][mid] < target) {
                l = mid + 1;
            }
        }
        return false;
    }

    public boolean searchMatrix1(int[][] matrix, int target) {
        int row = matrix.length;
        int col = matrix[0].length;
        int r = 0;
        int c = 0;
        if (row == 0 || col == 0)
            return false;
        if (target < matrix[0][0])
            return false;
        if (target > matrix[row - 1][col - 1])
            return false;
        for (int i = 0; i < row; i++) {
            System.out.println(matrix[i][0]);
            if (target > matrix[i][0]) {
                r = i;

            } else {
                break;
            }
        }
        for (int j = 0; j < col; j++) {
            if (matrix[r][j] == target) {
                return true;
            }
        }

        return false;
    }

    //73、矩阵置0
    public void setZeroes(int[][] matrix) {
        //原地算法,只用o(1)的额外空间,或者很小的固定的空间
        int row = matrix.length;
        int col = matrix[0].length;
        int flag_r = 0;
        int flag_c = 0;
        for (int i = 0; i < row; i++) {
            if (matrix[i][0] == 0)
                flag_r = 1;
        }
        for (int i = 0; i < col; i++) {
            if (matrix[0][i] == 0)
                flag_c = 1;
        }
        for (int i = 1; i < row; i++) {
            for (int j = 1; j < col; j++) {
                if (matrix[i][j] == 0) {
                    matrix[i][0] = matrix[0][j] = 0;
                }

            }
        }
        for (int i = 1; i < row; i++) {
            for (int j = 1; j < col; j++) {
                if (matrix[i][0] == 0 || matrix[0][j] == 0)
                    matrix[i][j] = 0;
            }
        }
        if (flag_r == 1) {
            for (int i = 0; i < row; i++) {
                matrix[i][0] = 0;
            }
        }
        if (flag_c == 1) {
            for (int i = 0; i < col; i++) {
                matrix[0][i] = 0;
            }
        }
    }

    //72、编辑距离
    public int minDistance(String word1, String word2) {

        return 0;
    }

    //71、简化路径
    public String simplifyPath(String path) {
        String[] str = path.split("/");
        Deque<String> stack = new ArrayDeque<>();
        for (int i = 0; i < str.length; i++) {
            //System.out.println(str[i]);
            if (str[i].equals(" ") || str[i].equals(""))
                continue;
            if (str[i].equals("."))
                continue;
            if (str[i].equals("..")) {
                if (!stack.isEmpty()) {
                    stack.pop();
                }
                continue;
            }
            if (str[i].equals("/"))
                continue;
            stack.push(str[i]);
        }
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("/");
        while (!stack.isEmpty()) {
            String temp = stack.peekLast();
            stringBuilder.append(temp);
            stringBuilder.append("/");
            stack.removeLast();
        }
        if (stringBuilder.length() == 1) {
            return stringBuilder.toString();
        }
        stringBuilder.deleteCharAt(stringBuilder.length() - 1);
        return stringBuilder.toString();
    }

    //70、爬楼梯
    public int climbStairs(int n) {
        int[] floor = new int[50];
        floor[0] = 0;
        floor[1] = 1;
        floor[2] = 2;
        for (int i = 3; i <= n; i++) {
            floor[i] = floor[i - 1] + floor[i - 2];
        }
        return floor[n];
    }

    //69、x的平方根
    public int mySqrt(int x) {
        if (x == 0)
            return 0;
        if (x == 1)
            return 1;
        for (int i = 0; i <= x / 2; i++) {
            if ((long) i * i <= x && (long) (i + 1) * (i + 1) >= x) {
                if ((long) i * i == x)
                    return i;
                if ((long) (i + 1) * (i + 1) == x)
                    return i + 1;
                return i;
            }
        }
        return 0;
    }

    public int mySqrt1(int x) {
        int l = 0, r = x;
        int ans = -1;
        while (l <= r) {
            int mid = l + (r - l) / 2;
            if ((long) mid * mid <= x) {
                ans = mid;
                l = mid + 1;
            } else {
                r = mid - 1;
            }
        }
        return ans;
    }

    //18、四数之和
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> res = new ArrayList<>();
        List<Integer> path = new ArrayList<>();
        int ans = 0;
        Arrays.sort(nums);
        dfs(nums, target, 0, path, res, ans);
        return res;
    }

    public void dfs(int[] nums, int target, int begin, List<Integer> path, List<List<Integer>> res, int ans) {
        if (path.size() == 4) {
            if (ans == target) {
                res.add(new ArrayList<>(path));
            }
            return;
        }
        for (int i = begin; i < nums.length; i++) {
            if (nums.length - i < 4 - path.size())
                return;
            if (i > begin && nums[i] == nums[i - 1])
                continue;
            if (i < nums.length - 1 && ans + nums[i] + (3 - path.size()) * nums[i + 1] > target)
                return;
            if (i < nums.length - 1 && ans + nums[i] + (3 - path.size()) * nums[nums.length - 1] < target)
                continue;
            ans += nums[i];
            path.add(nums[i]);
            dfs(nums, target, i + 1, path, res, ans);
            ans -= nums[i];
            path.remove(path.size() - 1);
        }
    }

    //17. 电话号码的字母组合
    Map<Character, String> phoneMap = new HashMap<>() {{
        put('2', "abc");
        put('3', "def");
        put('4', "ghi");
        put('5', "jkl");
        put('6', "mno");
        put('7', "pqrs");
        put('8', "tuv");
        put('9', "wxyz");
    }};

    public List<String> letterCombinations(String digits) {

        StringBuilder str = new StringBuilder();
        StringBuilder path = new StringBuilder();
        List<String> res = new ArrayList<>();
        if (digits.equals(""))
            return res;
        traceback(path, res, 0, digits);
        return res;
    }

    public void traceback(StringBuilder path, List<String> res, int depth, String dights) {
        if (depth == dights.length()) {
            res.add(path.toString());
        } else {
            char c = dights.charAt(depth);
            String letter = phoneMap.get(c);
            for (int i = 0; i < letter.length(); i++) {
                path.append(letter.charAt(i));
                traceback(path, res, depth + 1, dights);
                path.deleteCharAt(depth);
            }
        }
    }

    //16、最接近的三数之和
    public int threeSumClosest(int[] nums, int target) {
        int ans = 99999999;
        if (nums.length == 0)
            return 0;
        if (nums.length == 1)
            return nums[0];
        Arrays.sort(nums);
        for (int first = 0; first < nums.length; first++) {

            int third = nums.length - 1;
            int second = first + 1;
            while (second < third) {
                int sum = nums[first] + nums[second] + nums[third];
                if (sum == target)
                    return sum;
                if (Math.abs(sum - target) < Math.abs((ans - target))) {
                    ans = sum;
                }
                if (sum > target) {
                    int k = third - 1;
                    while (second < k && nums[third] == nums[k]) {
                        k--;
                    }
                    third = k;
                } else {
                    int v = second + 1;
                    while (v < third && nums[v] == nums[second]) {
                        v++;
                    }
                    second = v;
                }
            }
        }

        return ans;
    }

    //37、解数独
    List<int[]> spaces = new ArrayList<>();
    private boolean valid = false;
    boolean[][] row = new boolean[9][9];
    boolean[][] col = new boolean[9][9];
    boolean[][][] sub = new boolean[3][3][9];

    public void solveSudoku(char[][] board) {
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                if (board[i][j] != '.') {
                    int c = board[i][j] - '0' - 1;
                    row[i][c] = true;
                    col[j][c] = true;
                    sub[i / 3][j / 3][c] = true;
                } else {
                    spaces.add(new int[]{i, j});
                }
            }
        }
        dfs(board, 0);
    }

    public void dfs(char[][] board, int pos) {
        if (pos == spaces.size()) {
            valid = true;
            return;
        }
        int i = spaces.get(pos)[0];
        int j = spaces.get(pos)[1];
        for (int digit = 0; digit < 9 && !valid; digit++) {
            if (!row[i][digit] && !col[j][digit] && !sub[i / 3][j / 3][digit]) {
                row[i][digit] = col[j][digit] = sub[i / 3][j / 3][digit] = true;
                board[i][j] = (char) (digit + '0' + 1);
                dfs(board, pos + 1);
                row[i][digit] = col[j][digit] = sub[i / 3][j / 3][digit] = false;
            }


        }


    }

    //36、有效的数独
    public boolean isValidSudoku(char[][] board) {
        int len = board.length;
        int[][] row = new int[len][len];
        int[][] col = new int[len][len];
        int[][][] sub = new int[len][len][9];
        for (int i = 0; i < len; i++) {
            for (int j = 0; j < len; j++) {
                if (board[i][j] != '.') {
                    int c = board[i][j] - '0' - 1;
                    row[i][c]++;
                    col[j][c]++;
                    sub[i / 3][j / 3][c]++;
                    if (row[i][c] > 1 || col[j][c] > 1 || sub[i / 3][j / 3][c] > 1) {
                        return false;
                    }
                }
            }
        }

        return true;
    }

    //84. 柱状图中最大的矩形
    public int largestRectangleArea(int[] heights) {
        int len = heights.length;
        if (len == 0)
            return 0;
        if (len == 1) {
            return heights[0];
        }
        int area = 0;
        int[] newHeights = new int[len + 2];
        for (int i = 0; i < len; i++) {
            newHeights[i + 1] = heights[i];
        }
        len += 2;
        heights = newHeights;
        Deque<Integer> stack = new ArrayDeque<>();
        stack.addLast(0);
        for (int i = 1; i < len; i++) {
            while (heights[stack.peekLast()] > heights[i]) {
                int height = heights[stack.removeLast()];
                int width = i - stack.peekLast() - 1;
                area = Math.max(area, height * width);
            }
            stack.addLast(i);
        }
        return area;
    }

    //15、三数之和
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();

        Arrays.sort(nums);
        int second = 0;
        int third = 0;
        for (int first = 0; first < nums.length; first++) {
            if (first > 0 && nums[first] == nums[first - 1])
                continue;
            third = nums.length - 1;
            int target = -nums[first];
            for (second = first + 1; second < nums.length; second++) {
                if (second > first + 1 && nums[second] == nums[second - 1])
                    continue;
                while (second < third && nums[second] + nums[third] > target) {
                    third--;
                }
                if (second == third) {
                    break;
                }
                if (nums[second] + nums[third] == target) {
                    List<Integer> path = new ArrayList<>();
                    path.add(nums[first]);
                    path.add(nums[second]);
                    path.add(nums[third]);
                    res.add(path);
                }
            }
        }

        return res;
    }

    //14、最长公共前缀
    public String longestCommonPrefix(String[] strs) {

        int row = strs.length;
        if (row == 1)
            return strs[0];
        if (row == 0)
            return null;
        int col = 99999999;
        for (int i = 0; i < row; i++) {
            col = Math.min(col, strs[i].length());
        }
        StringBuilder stringBuilder = new StringBuilder();
        for (int j = 0; j < col; j++) {
            char ch = strs[0].charAt(j);
            for (int i = 1; i < row; i++) {
                if (strs[i].charAt(j) != ch) {
                    return stringBuilder.toString();
                }
                if (i == row - 1) {
                    stringBuilder.append(ch);
                }
            }
        }
        return stringBuilder.toString();
    }

    //10. 正则表达式匹配
    public boolean isMatch(String s, String p) {
        int m = s.length();
        int n = p.length();
        boolean[][] f = new boolean[m + 1][n + 1];
        f[0][0] = true;
        for (int i = 0; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (p.charAt(j - 1) == '*') {
                    f[i][j] = f[i][j - 2];
                    if (matches(s, p, i, j - 1)) {
                        f[i][j] = f[i][j] || f[i - 1][j];
                    }

                } else {
                    if (matches(s, p, i, j)) {
                        f[i][j] = f[i - 1][j - 1];
                    }
                }
            }
        }
        return f[m][n];
    }

    public boolean matches(String s, String p, int i, int j) {
        if (i == 0)
            return false;
        if (p.charAt(j - 1) == '.')
            return true;
        if (s.charAt(i - 1) == p.charAt(j - 1))
            return true;
        return false;
    }

    //9、回文数
    public boolean isPalindrome(int x) {
        String str = Integer.toString(x);
        int len = str.length();
        int i = 0, j = len - 1;
        while (i <= j) {
            if (str.charAt(i) == str.charAt(j)) {
                i++;
                j--;
            } else
                return false;
        }
        return true;
    }


    //13、罗马数字转整数
    public int romanToInt(String s) {
        Map<Character, Integer> symbolValues = new HashMap<Character, Integer>() {{
            put('I', 1);
            put('V', 5);
            put('X', 10);
            put('L', 50);
            put('C', 100);
            put('D', 500);
            put('M', 1000);
        }};
        int ans = 0;
        int len = s.length();
        for (int i = 0; i < len; i++) {
            int value = symbolValues.get(s.charAt(i));
            if (i < len - 1 && value < symbolValues.get(s.charAt(i + 1))) {
                ans -= value;
            } else {
                ans += value;
            }
        }
        return ans;
    }

    //12、整数转罗马数字
    public String intToRoman(int num) {
        String[] thousands = {"", "M", "MM", "MMM"};
        String[] hundreds = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
        String[] tens = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
        String[] ones = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
        StringBuffer roman = new StringBuffer();
        roman.append(thousands[num / 1000]);
        roman.append(hundreds[num % 1000 / 100]);
        roman.append(tens[num % 100 / 10]);
        roman.append(ones[num % 10]);
        return roman.toString();
    }

    //11. 盛最多水的容器
    public int maxArea(int[] height) {

        int len = height.length;
        int i = 0, j = len - 1;
        int ans = 0;
        while (i <= j) {
            int h = Math.min(height[i], height[j]);
            ans = Math.max(ans, h * (j - i));
            if (height[j] < height[i]) {
                j--;
            } else {
                i++;
            }
        }
        return ans;
    }

    //8、字符串转换整数 (atoi)
    public int myAtoi(String str) {
        int res = 0;
        int len = str.length();

        char[] charArray = str.toCharArray();
        int index = 0;
        while (index < len && charArray[index] == ' ')
            index++;
        if (index == len)
            return 0;
        int sign = 1;
        char firstChar = charArray[index];
        if (firstChar == '+') {
            index++;
        } else {
            if (firstChar == '-') {
                index++;
                sign = -1;
            }
        }
        while (index < len) {
            char currentArray = charArray[index];
            if (currentArray > '9' || currentArray < '0')
                break;
            if (res > Integer.MAX_VALUE / 10 || (res == Integer.MAX_VALUE / 10 && (currentArray - '0') > Integer.MAX_VALUE % 10)) {
                return Integer.MAX_VALUE;
            }
            if (res < Integer.MIN_VALUE / 10 || (res == Integer.MIN_VALUE / 10 && (currentArray - '0') > -(Integer.MIN_VALUE % 10))) {
                return Integer.MIN_VALUE;
            }
            res = res * 10 + sign * (currentArray - '0');
            index++;

        }
        return res;
    }

    public int trap(int[] height) {
        int len = height.length;
        int ans = 0;
        int[] left = new int[len];
        int[] right = new int[len];
        left[0] = height[0];
        for (int i = 1; i < len; i++) {
            left[i] = Math.max(left[i - 1], height[i]);
        }
        right[len - 1] = height[len - 1];
        for (int i = len - 2; i >= 0; i--) {
            right[i] = Math.max(right[i + 1], height[i]);
        }

        for (int i = 1; i < len - 1; i++) {
            ans += Math.min(left[i], right[i]) - height[i];
        }

        return ans;
    }

    //42. 接雨水
    public int trap1(int[] height) {
        //暴力解法
        int ans = 0;
        for (int i = 0; i < height.length; i++) {
            int l = 0;
            int r = 0;
            for (int j = i; j >= 0; j--) {
                l = Math.max(l, height[j]);
            }
            for (int j = i; j < height.length; j++) {
                r = Math.max(r, height[j]);
            }
            ans += Math.min(l, r) - height[i];
        }
        return ans;
    }

    //7.整数反转
    public int reverse(int x) {
        //最大的32位整数是2147483647
        int res = 0;
        int temp = 0;
        while (x != 0) {
            temp = x % 10;
            if (res > 214748364 || (res == 214748364 && temp == 7)) {
                return 0;
            }
            if (res < -214748364 || (res == -214748364 && temp == 7)) {
                return 0;
            }
            res = res * 10 + temp;
            x /= 10;

        }
        return res;
    }

    //6. Z 字形变换
    public String convert1(String s, int numRows) {
        System.out.println(s);
        char[][] ch = new char[numRows][1000];
        int k = 0;
        int i = 0, j = 0;
        while (k < s.length()) {
            if (i == 0) {
                while (i < numRows && k < s.length()) {
                    ch[i++][j] = s.charAt(k++);
                }
            }
            if (i == numRows) {
                i--;
                while (i > 0 && k < s.length())
                    ch[i--][j++] = s.charAt(k++);
            }
        }
        StringBuilder stringBuilder = new StringBuilder();
        for (int t = 0; t < j; t++) {
            for (i = 0; i < numRows; i++) {
                if (ch[i][t] != ' ') {
                    System.out.println(ch[i][t]);
                }

            }
        }
        return stringBuilder.toString();


    }

    public String convert(String s, int numRows) {
        int n = s.length(), r = numRows;
        if (r == 1 || r >= n) {
            return s;
        }
        int t = r * 2 - 2;
        int c = (n + t - 1) / t * (r - 1);
        char[][] mat = new char[r][c];
        for (int i = 0, x = 0, y = 0; i < n; ++i) {
            mat[x][y] = s.charAt(i);
            if (i % t < r - 1) {
                ++x; // 向下移动
            } else {
                --x;
                ++y; // 向右上移动
            }
        }
        StringBuffer ans = new StringBuffer();
        for (char[] row : mat) {
            for (char ch : row) {
                if (ch != 0) {
                    ans.append(ch);
                }
            }
        }
        return ans.toString();
    }


    //5. 最长回文子串
    public String longestPalindrome(String s) {
        if (s.length() == 1 || s.equals(" "))
            return s;
        int len = s.length();
        boolean[][] dp = new boolean[len][len];
        int begin = 0;
        int maxLen = 1;
        for (int i = 0; i < len; i++) {
            dp[i][i] = true;
        }
        for (int l = 2; l <= len; l++) {
            for (int i = 0; i < len; i++) {
                int j = l + i - 1;
                if (j >= len) {
                    break;
                }
                if (s.charAt(i) != s.charAt(j)) {
                    dp[i][j] = false;
                } else {
                    if (j - i < 3) {
                        dp[i][j] = true;
                    } else {
                        dp[i][j] = dp[i + 1][j - 1];
                    }

                }
                if (dp[i][j] && j - i + 1 > maxLen) {
                    maxLen = j - i + 1;
                    begin = i;
                }

            }
        }
        return s.substring(begin, begin + maxLen);

    }

    //寻找两个正序数组的中位数
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int len1 = nums1.length;
        int len2 = nums2.length;
        int i = 0, j = 0;
        int[] arr = new int[len1 + len2];
        int k = 0;
        double ans = 0;
        while (i < len1 && j < len2) {
            if (nums1[i] <= nums2[j]) {
                arr[k++] = nums1[i];
                i++;
            } else {
                arr[k++] = nums2[j];
                j++;
            }
        }
        while (i < len1) {
            arr[k++] = nums1[i];
            i++;
        }
        while (j < len2) {
            arr[k++] = nums2[j];
            j++;
        }
        if ((len1 + len2) % 2 == 0) {
            ans = 1.0 * (arr[(len1 + len2) / 2 - 1] + arr[(len1 + len2) / 2]) / 2;

        } else {
            ans = 1.0 * (arr[(len1 + len2) / 2]);
        }
        return ans;
    }
    //得分情况

    /***
     * 一张100分试卷,判断10*2,单选10*4,多选5*8,从前往后做,错三个离场,
     * 给定一个成绩,问有多少种情况
     * */
    public void gradeDivider() {
        Scanner sc = new Scanner(System.in);
        int grade = 100;
        int count = 0;
        for (int i = 0; i <= 3; i++) {
            for (int j = 0; j <= 3; j++) {
                for (int k = 0; k <= 3; k++) {

                    if ((i + j + k) != 3) {
                        continue;
                    } else {
                        if ((10 - i) * 2 + (10 - j) * 4 + (5 - k) * 8 == grade) {
                            count++;
                        }
                    }
                    System.out.println(i + " " + j + " " + k);
                    System.out.println("-----------------");
                }
            }
        }

    }

    //力扣 3、无重复字符的最长字串
    public int lengthOfLongestSubstring(String s) {
        int l = 0;
        int maxLen = 0;
        if (s.equals(" ")) {
            return 1;
        }
        if (s.length() == 1) {
            return 1;
        }
        HashMap<Character, Integer> map = new HashMap<>();
        int i = 0;
        for (i = 0; i < s.length(); i++) {
            if (map.get(s.charAt(i)) == null)
                map.put(s.charAt(i), i);
            else {
                l = Math.max(l, map.get(s.charAt(i)) + 1);
                map.put(s.charAt(i), i);
            }
            maxLen = Math.max(maxLen, i - l + 1);
        }

        return maxLen;
    }
    //两数相加

    /****
     * 给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
     *
     * 请你将两个数相加,并以相同形式返回一个表示和的链表。
     *
     * 来源:力扣(LeetCode)
     * 链接:https://leetcode-cn.com/problems/add-two-numbers
     * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
     */
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode p1 = l1;
        ListNode p2 = l2;
        int num1;
        int sum1 = 0;
        int count = 0;
        int temp = 0;
        int sum = 0;
        ListNode listNode = new ListNode();
        sum = (p1.val + p2.val);
        temp = sum / 10;
        listNode.val = sum % 10;
        ListNode t = listNode;
        p1 = p1.next;
        p2 = p2.next;
        while (p1 != null && p2 != null) {
            ListNode p = new ListNode();
            sum = p1.val + p2.val;
            p.val = (sum + temp) % 10;
            temp = (sum + temp) / 10;
            t.next = p;
            t = p;
            p1 = p1.next;
            p2 = p2.next;

        }
        while (p1 != null) {
            ListNode p = new ListNode();
            sum = (p1.val + temp);
            temp = sum / 10;
            p.val = sum % 10;
            t.next = p;
            t = p;
            p1 = p1.next;
        }
        while (p2 != null) {
            ListNode p = new ListNode();
            sum = p2.val + temp;
            temp = sum / 10;
            p.val = sum % 10;
            t.next = p;
            t = p;
            p2 = p2.next;
        }
        if (temp != 0) {
            ListNode p = new ListNode();
            p.val = temp;
            t.next = p;
        }
        return listNode;
    }

    //HJ4 字符串分隔
    /*
    •输入一个字符串,请按长度为8拆分每个输入字符串并进行输出;
    •长度不是8整数倍的字符串请在后面补数字0,空字符串不处理。
    **/
    public void spiltStr() {
        Scanner sc = new Scanner(System.in);
        String str = sc.next();
        if (str.length() == 8) {
            System.out.println(str);
        }

        if (str.length() < 8) {
            StringBuilder s = new StringBuilder();
            s.append(str);
            for (int i = str.length(); i < 8; i++) {
                s.append(0);

            }
            System.out.println(s.toString());
            return;
        }
        int len = str.length();
        int temp = 0;
        if (len % 8 == 0) {
            temp = len / 8;
        }
        int i = 0;
        for (i = 0; i <= temp * 8; i += 8) {
            String strTemp = str.substring(i, i + 8);
            System.out.println(strTemp);
        }
        if (i == len) {
            return;
        } else {
            StringBuilder s = new StringBuilder();
            String strTemp = str.substring(i, len);
            s.append(strTemp);
            for (; i < len; i++) {
                s.append(0);
            }
            System.out.println(s.toString());
        }
    }


    //HJ2 计算某字符出现次数
    public int countChar() {
        Scanner sc = new Scanner(System.in);
        String str = sc.next();
        char c = sc.next().charAt(0);
        int count = 0;
        for (int i = 0; i < str.length(); i++) {
            if (str.charAt(i) == c) {
                count++;
            }
        }
        return count;

    }

    //字符串最后一个字符
    /*计算字符串最后一个单词的长度,单词以空格隔开,字符串长度小于5000。(注:字符串末尾不以空格为结尾)
     * */
    public int lastLength() {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        char[] ch = str.toCharArray();
        int len = str.length();
        System.out.println(str);
        int count = 0;
        for (int i = len - 1; i >= 0; i--) {
            if (ch[i] == ' ') {
                return count;
            } else count++;
        }
        return count;
    }


    //力扣 67、二进制求和
    /*给你两个二进制字符串,返回它们的和(用二进制表示)。
      输入为 非空 字符串且只包含数字 1 和 0。
    * */
    public String addBinary(String a, String b) {
        StringBuilder ans = new StringBuilder();
        int ca = 0;
        for (int i = a.length() - 1, j = b.length() - 1; i >= 0 || j >= 0; i--, j--) {
            int sum = ca;
            sum += i >= 0 ? a.charAt(i) - '0' : 0;
            sum += j >= 0 ? b.charAt(j) - '0' : 0;
            ans.append(sum % 2);
            ca = sum / 2;
        }
        ans.append(ca == 1 ? ca : "");
        return ans.reverse().toString();
    }

    public String addBinary1(String a, String b) {
        if (a.equals("") || b.equals(" ")) {
            return null;
        }
        int lena = a.length();
        int lenb = b.length();
        int minLen = Math.max(lena, lenb);
        int temp = 0;
        StringBuilder sa = new StringBuilder();
        StringBuilder sb = new StringBuilder();
        for (int i = lena - 1; i >= 0; i--) {
            sa.append(a.charAt(i));
        }
        for (int i = lenb - 1; i >= 0; i--) {
            sb.append(b.charAt(i));
        }
        StringBuilder s = new StringBuilder();
        int i = 0;
        for (i = 0; i < minLen; i++) {
            s.append((sa.charAt(i) - '0' + sb.charAt(i) - '0' + temp) % 2);
            temp = (sa.charAt(i) - '0' + sb.charAt(i) - '0' + temp) / 2;
        }
        while (i < lena) {
            s.append((sa.charAt(i) + temp) % 2);
            temp = (sa.charAt(i) + temp) / 2;
            i++;
        }
        while (i < lenb) {
            s.append((sb.charAt(i) + temp) % 2);
            temp = (sb.charAt(i) + temp) / 2;
            i++;
        }
        if (temp == 1) {
            s.append(temp);
        }
        String str = s.reverse().toString();
        return str;
    }


    //力扣 66、加1
    /*给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。
    最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
    你可以假设除了整数 0 之外,这个整数不会以零开头。
    * */
    public int[] plusOne(int[] digits) {
        if (digits[digits.length - 1] < 9) {
            digits[digits.length - 1] += 1;
            return digits;
        } else {

            StringBuilder s = new StringBuilder();
            StringBuilder res = new StringBuilder();
            for (int i = digits.length - 1; i >= 0; i--) {
                s.append(digits[i]);
            }
            String str = s.toString();
            int temp = 0;
            res.append((str.charAt(0) - '0' + 1) % 10);
            temp = (str.charAt(0) - '0' + 1) / 10;
            for (int i = 1; i < digits.length; i++) {
                res.append((str.charAt(i) - '0' + temp) % 10);
                temp = (str.charAt(i) - '0' + temp) / 10;
            }
            if (temp == 1) {
                res.append(temp);
            }
            str = res.reverse().toString();
            int[] ans = new int[res.length()];
            for (int i = 0; i < str.length(); i++) {
                ans[i] = str.charAt(i) - '0';
            }
            return ans;
        }
    }

    //用两个线程交替打印奇偶数
    private int count = 0;
    private final Object lock = new Object();

    public void turning() throws InterruptedException {
        Thread even = new Thread(() -> {
            while (count <= 100) {
                synchronized (lock) {
                    System.out.println("偶数: " + count++);
                    lock.notifyAll();
                    try {
                        // 如果还没有结束,则让出当前的锁并休眠
                        if (count <= 100) {
                            lock.wait();
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        Thread odd = new Thread(() -> {
            while (count <= 100) {
                synchronized (lock) {
                    System.out.println("奇数: " + count++);
                    lock.notifyAll();
                    try {
                        // 如果还没有结束,则让出当前的锁并休眠
                        if (count <= 100) {
                            lock.wait();
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        even.start();
        // 确保偶数线程线先获取到锁
        Thread.sleep(1);
        odd.start();
    }

    //有效数字
    public boolean isNumber(String s) {
        if (null == s || s.length() == 0) {
            return false;
        }
        //防止多个.或者e的情况
        if (s.indexOf(".") != s.lastIndexOf(".") || s.indexOf("e") != s.lastIndexOf("e")) {
            return false;
        }
        if (s.contains(".")) {
            if (s.length() == 1) {
                return false;
            }
            String[] splitArr = s.split("\\.");
            //防止.+的情况
            if (splitArr.length == 1 && splitArr[0].length() == 1 && (splitArr[0].contains("+") || splitArr[0].contains("-"))) {
                return false;
            }
            //防止.e的情况
            if (splitArr.length == 2 && splitArr[0].length() == 0 && (splitArr[1].startsWith("E") || splitArr[1].startsWith("e"))) {
                return false;
            }
            //防止e为在小数点之前的情况
            if (splitArr[0].contains("e") || splitArr[0].contains("E")) {
                return false;
            }
            //小数点分割出的每一段,都去做校验
            for (String str : splitArr) {
                if (!check(str, true)) {
                    return false;
                }
                count++;
            }
        } else {
            if (!check(s, false)) {
                return false;
            }
        }
        return true;
    }

    //校验方法,能同时校验小数点分割的情况、没有小数点的情况
    //flag作为是否产生小数点分割的标志位
    public boolean check(String s, boolean flag) {
        if (count == 0 && (s.startsWith("e") || s.startsWith("E"))) {
            return false;
        }
        boolean eFlag = s.contains("e");
        boolean EFlag = s.contains("E");
        if (eFlag || EFlag) {
            String[] split = null;
            if (eFlag) {
                split = s.split("e");
            } else {
                split = s.split("E");
            }
            if (split.length != 2) {
                return false;
            }
            for (String str : split) {
                boolean symbolFlag = false;
                if (str.startsWith("+") || str.startsWith("-")) {
                    symbolFlag = true;
                }
                int i = 0;
                if (symbolFlag) {
                    i++;
                }
                for (; i < str.length(); i++) {
                    char charAt = str.charAt(i);
                    if (charAt < 48 || charAt > 57) {
                        return false;
                    }
                }
                //校验仅有单符号的情景,比如4e+
                if (symbolFlag && str.length() == 1) {
                    return false;
                }
            }
        } else {
            boolean symbolFlag = false;
            if (s.startsWith("+") || s.startsWith("-")) {
                symbolFlag = true;
            }
            //如果这是根据小数点分割的第二个字符串,且以+号开头,则直接返回false。类似1.+56
            if (count == 1 && symbolFlag && flag) {
                return false;
            }
            int i = 0;
            if (symbolFlag) {
                i++;
            }
            //根据小数点,e分割完了之后,字符串片段中,不是开头的部分只能为数字,否则都是无效的
            for (; i < s.length(); i++) {
                char charAt = s.charAt(i);
                if (charAt < 48 || charAt > 57) {
                    return false;
                }
            }
        }
        return true;
    }

    //剑指 Offer II 095. 最长公共子序列 力扣 阿里
    public int longestCommonSubsequence(String text1, String text2) {
        int res;
        int len1 = text1.length();
        int len2 = text2.length();
        int[][] dp = new int[len1 + 1][len2 + 1];
        for (int i = 1; i <= len1; i++) {
            char ch1 = text1.charAt(i - 1);
            for (int j = 1; j <= len2; j++) {
                char ch2 = text2.charAt(j - 1);
                if (ch1 == ch2) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } else
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);

            }
        }
        return dp[len1][len2];
    }

    //剑指 Offer 27. 二叉树的镜像 力扣  阿里
    public TreeNode mirrorTree(TreeNode root) {
        if (root == null) {
            return null;
        }
        TreeNode left = mirrorTree(root.left);
        TreeNode right = mirrorTree(root.right);
        root.left = right;
        root.right = left;
        return root;
    }

    //力扣 最小覆盖字串 滑动窗口
    public String minWindow(String s, String t) {
        String ans = null;
        if (s == null || s.length() == 0 || t == null || t.length() == 0) {
            return " ";
        }
        int lens = s.length();
        int lent = t.length();
        HashMap<Character, Integer> map = new HashMap<>();
        for (int i = 0; i < lent; i++) {
            map.put(s.charAt(i), map.getOrDefault(s.charAt(i), 0) + 1);
        }
        int l = 0, r = 0, count = 0;

        for (int i = 0; i < lent; i++) {

        }
        return ans;

    }

    //力扣 串联所有单词的子串 滑动窗口
    public List<Integer> findSubstring(String s, String[] words) {
        List<Integer> res = new ArrayList<>();
        int one_word = words[0].length();
        int word_num = words.length;
        int all_len = one_word * word_num;
        int len = s.length();
        if (s == null || s.length() == 0 || words == null || words.length == 0)
            return res;

        HashMap<String, Integer> map = new HashMap<>();
        for (String word : words) {
            map.put(word, map.getOrDefault(word, 0) + 1);
        }
        for (int i = 0; i < one_word; i++) {
            HashMap<String, Integer> tmp_map = new HashMap<>();
            int l = i, r = i, count = 0;
            while (r + one_word <= len) {

                String w = s.substring(r, r + one_word);
                r += one_word;
                if (!map.containsKey(w)) {
                    count = 0;
                    l = r;
                    tmp_map.clear();
                } else {
                    tmp_map.put(w, tmp_map.getOrDefault(w, 0) + 1);
                    count++;
                    while (tmp_map.getOrDefault(w, 0) > map.getOrDefault(w, 0)) {
                        String tmp_w = s.substring(l, l + one_word);
                        count--;
                        tmp_map.put(tmp_w, tmp_map.getOrDefault(tmp_w, 0) - 1);
                        l += one_word;
                    }
                    if (count == word_num) {
                        res.add(l);
                    }
                }
            }
        }
        return res;
    }

    //力扣 无重复字符的最长字串 滑动窗口
    public int lengthOfLongestSubstring1(String s) {

        int len = s.length();
        int max = 0;
        int left = 0;
        HashMap<Character, Integer> map = new HashMap<>();
        for (int i = 0; i < len; i++) {
            if (map.containsKey(s.charAt(i))) {
                left = Math.max(left, map.get(s.charAt(i)) + 1);
            }
            map.put(s.charAt(i), i);
            max = Math.max(max, i - left + 1);
        }
        return max;
    }

    // 字节 ZJ2
    public static String solve2(long n, long k, long d1, long d2) {
        long left;
        //第一种情况
        long m1 = k + 2 * d1 + d2;
        if (m1 >= 0 && m1 % 3 == 0) {
            left = (n - k) - (2 * d1 + d2);
            if (left >= 0 && left % 3 == 0) {
                return "yes";
            }
        }
        //第二种情况
        long m2 = k + 2 * d1 - d2;
        if (m2 >= 0 && m2 % 3 == 0) {
            if (d1 >= d2) {
                left = (n - k) - (2 * d1 - d2);
            } else {
                left = (n - k) - (2 * d2 - d1);
            }
            if (left >= 0 && left % 3 == 0) {
                return "yes";
            }

        }
        //第三种情况
        long m3 = k - 2 * d1 + d2;
        if (m3 >= 0 && m3 % 3 == 0) {
            left = (n - k) - (d1 + d2);
            if (left >= 0 && left % 3 == 0) {
                return "yes";
            }

        }
        //第四种情况
        long m4 = k - (2 * d1 + d2);
        if (m4 >= 0 && m4 % 3 == 0) {
            left = (n - k) - (d1 + 2 * d2);
            if (left >= 0 && left % 3 == 0) {
                return "yes";
            }
        }
        return "no";
    }

    // 力扣  最小路径和
    public int minPathSum(int[][] grid) {
        int m = grid.length;
        int n = grid[0].length;
        int[][] dp = new int[m][n];//dp数组用来保存到达dp[i][j]的最小路径和
        dp[0][0] = grid[0][0];
        //初始化边界问题
        for (int i = 1; i < m; i++) {
            dp[i][0] = dp[i - 1][0] + grid[i][0];
        }
        for (int j = 1; j < n; j++) {
            dp[0][j] = dp[0][j - 1] + grid[0][j];
        }
        //求每一步的最小路径之和
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                dp[i][j] = Math.min(dp[i - 1][j] + grid[i][j], dp[i][j - 1] + grid[i][j]);
            }

        }
        return dp[m - 1][n - 1];
    }

    //不同路径II 网格中间加入了障碍物
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        //求出网格的行和列
        int m = obstacleGrid.length;
        int n = obstacleGrid[0].length;
        int[][] path = new int[m][n];
        //下面两个for循环是处理边界的
        for (int i = 0; i < m; i++) {
            if (obstacleGrid[i][0] == 1) {
                for (int j = i; j < m; j++) {
                    path[j][0] = 0;
                }
                break;
            } else path[i][0] = 1;
        }
        for (int i = 0; i < n; i++) {
            if (obstacleGrid[0][i] == 1) {
                for (int j = i; j < n; j++) {
                    path[0][j] = 0;
                }
                break;
            } else
                path[0][i] = 1;
        }
        //这个for循环是处理网格除了边界的
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                if (obstacleGrid[i][j] == 1) {
                    path[i][j] = 0;
                }
            }

        }
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                if (obstacleGrid[i][j] == 1)
                    path[i][j] = 0;
                else
                    path[i][j] = path[i - 1][j] + path[i][j - 1];
            }
        }
        return path[m - 1][n - 1];
    }

    //不同路径(动态规划)
    public int uniquePaths(int m, int n) {
        int[][] path = new int[m][n];//path[i][j]代表走到i,j位置有多少种路径
        //初始化path数组,0行的所有列和0列的所有行都只有一种方案
        for (int i = 0; i < m; i++) {
            path[i][0] = 1;
        }
        for (int i = 0; i < n; i++) {
            path[0][i] = 1;
        }
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                path[i][j] = path[i - 1][j] + path[i][j - 1];
            }
        }
        return path[m - 1][n - 1];
    }

    public String getPermutation(int n, int k) {
        this.n = n;
        this.k = k;
        calculateFactorial(n);

        used = new boolean[n + 1];
        Arrays.fill(used, false);

        StringBuilder path = new StringBuilder();
        dfs(0, path);
        return path.toString();

    }

    //回溯+剪枝
    public void dfs(int index, StringBuilder path) {
        if (index == n) {
            return;
        }
        int count = factorial[n - 1 - index];
        for (int i = 1; i <= n; i++) {
            if (used[i]) {
                continue;
            }
            if (k > count) {
                k -= count;
                continue;
            }
            path.append(i);
            used[i] = true;
            dfs(index + 1, path);
            return;
        }
    }

    //计算阶乘数组
    public void calculateFactorial(int n) {
        factorial = new int[n + 1];
        factorial[0] = 1;
        for (int i = 1; i <= n; i++) {
            factorial[i] = factorial[i - 1] * i;
        }

    }

    public ListNode rotateRight(ListNode head, int k) {
        int len;//链表长度
        if (head == null) {
            return null;
        }
        len = 1;
        ListNode node = new ListNode();//这个node是为了计算链表的长度,并指向链表末尾
        node = head;
        while (node.next != null) {
            len++;
            node = node.next;
        }
        ListNode posNode;//旋转位置的链表节点
        k %= len;
        if (k == 0)
            return head;
        int pos = len - k;//旋转位置
        ListNode preNode; //记录旋转节点的前一个节点
        ListNode tempNode = head;//遍历链表的节点
        preNode = tempNode;
        int count = 0;
        while (count != pos) {
            count++;
            preNode = tempNode;
            tempNode = tempNode.next;
        }
        preNode.next = null;
        node.next = head;
        head = tempNode;
        return head;
    }

    //飞地的数量
    public int numEnclaves(int[][] grid) {
        int res = 0;
        int m = grid.length;
        int n = grid[0].length;
        boolean[][] vis = new boolean[m][n];
        for (int i = 0; i < m; i++) {
            dfs(grid, i, 0);
            dfs(grid, i, n - 1);
        }
        for (int j = 1; j < n; j++) {
            dfs(grid, 0, j);
            dfs(grid, m - 1, j);

        }
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 1 && vis[i][j] == false) {
                    res++;
                }
            }
        }
        return res;
    }

    public void dfs(int[][] grid, int x, int y) {
        if (x < 0 || y < 0 || vis[x][y] || grid[x][y] == 0) {
            return;
        }
        vis[x][y] = true;
        dfs(grid, x + 1, y);
        dfs(grid, x - 1, y);
        dfs(grid, x, y + 1);
        dfs(grid, x, y - 1);
    }



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值