代码随想录刷题记录

二刷

文章目录

数组

704. 二分查找 - 力扣(LeetCode)

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

        return -1;
    }
}

27. 移除元素 - 力扣(LeetCode)

class Solution {
    public int removeElement(int[] nums, int val) {
        int low = 0, fast = 0;
        while (fast < nums.length) {
            while (fast < nums.length && nums[fast] == val) fast++;
            if (fast == nums.length) break;
            nums[low++] = nums[fast++];
        }

        return low;
    }
}

977. 有序数组的平方 - 力扣(LeetCode)

class Solution {
    public int[] sortedSquares(int[] nums) {
        int[] res = new int[nums.length];
        int l = 0, r = nums.length - 1, i = 0;
        while (l <= r) {
            if (nums[l] * nums[l] < nums[r] * nums[r]) {
                res[nums.length - 1 - i] = nums[r] * nums[r];
                r--;
            } else {
                res[nums.length - 1 - i] = nums[l] * nums[l];
                l++;
            }

            i++;
        }

        return res;
    }
}

209. 长度最小的子数组 - 力扣(LeetCode)

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int l = 0, r = 0;
        int res = nums.length + 1;
        int sum = 0;
        while (r < nums.length) {
            while (r < nums.length && sum < target) {
                sum += nums[r];
                r++;
            }
            
            while (sum >= target) {
                res = Math.min(r - l, res);
                sum -= nums[l];
                l++;     
            }
            
            
        }

        return res == nums.length + 1 ? 0 : res;
    }
}

59. 螺旋矩阵 II - 力扣(LeetCode)

class Solution {
    public int[][] generateMatrix(int n) {
        int[][] res = new int[n][n];
        
        int loop = 0, start = 0, num = 1, x = 0, y = 0;

        while (loop < n / 2) {
            // 右
            for (y = start, x = start; y < n - 1 - start; y++) {
                res[x][y] = num++;
            } 
            // 下
            for (; x < n - 1 - start; x++) {
                res[x][y] = num++;
            }
            // 左
            for (; y > start; y--) {
                res[x][y] = num++;
            }
            // 上
            for (; x > start; x--) {
                res[x][y] = num++;
            }
            start++;
            loop++;
        }

        if (n % 2 == 1) {
            res[n / 2][n / 2] = num;
        }

        return res;
    }
}

链表

203. 移除链表元素 - 力扣(LeetCode)

/**
 * 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 removeElements(ListNode head, int val) {
        ListNode dimmy = new ListNode(0);
        ListNode pre = dimmy;
        pre.next = head;
        while (head != null) {
            while (head != null && head.val == val) head = head.next;
            pre.next = head;
            pre = pre.next;
            if (head != null)head = head.next;
            else break;
        }

        return dimmy.next;
    }
}

707. 设计链表 - 力扣(LeetCode)

class MyLinkedList {
    ListNode head;
    int len;
    public MyLinkedList() {
        head = new ListNode(0);
        len = 0;
    }
    
    public int get(int index) {
        if (index < 0 || index >= len) return -1;
        if (index == 0) return head.val;
        ListNode cur = head;
        while (index > 0) {
            cur = cur.next;
            index--;
        }
        return cur.val;
    }
    
    public void addAtHead(int val) {
        if (len == 0) {
            head = new ListNode(val);
            len++;
            return;
        }
        ListNode tmp = new ListNode(val);
        tmp.next = head;
        head = tmp;
        len++;
    }
    
    public void addAtTail(int val) {
        if (len == 0) {
            addAtHead(val);
            return;
        }
        ListNode tmp = head;
        while (tmp.next != null) tmp = tmp.next;
        tmp.next = new ListNode(val);
        len++;
    }
    
    public void addAtIndex(int index, int val) {
        if (index > len || index < 0) return;
        if (index == 0) {
            addAtHead(val);
            return;
        }
        if (index == len) {
            addAtTail(val);
            return;
        }
        ListNode tmp = head;
        while (--index > 0) {
            tmp = tmp.next;
        }
        ListNode tmp2 = new ListNode(val);
        ListNode tmp3 = tmp.next;
        tmp.next = tmp2;
        tmp2.next = tmp3;
        len++;
    }
    
    public void deleteAtIndex(int index) {
        if (index < 0 || index >= len) return;
        if (index == 0) {
            head = head.next;
            len--;
            return;
        }
        ListNode tmp = head;
        while (--index > 0) {
            tmp = tmp.next;
        }

        tmp.next = tmp.next.next;
        len--;
    }
}


/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList obj = new MyLinkedList();
 * int param_1 = obj.get(index);
 * obj.addAtHead(val);
 * obj.addAtTail(val);
 * obj.addAtIndex(index,val);
 * obj.deleteAtIndex(index);
 */

 class ListNode {
     int val;
     ListNode next;

     public ListNode (int val) {
         this.val = val;
     }
 }

// 注释部分为我的代码
class MyLinkedList {
    ListNode head;
    int len;
    public MyLinkedList() {
        head = new ListNode(0);
        len = 0;
    }
    
    public int get(int index) {
        if (index < 0 || index >= len) return -1;
        if (index == 0) return head.val;
        ListNode cur = head;
        while (index > 0) {
            cur = cur.next;
            index--;
        }
        return cur.val;
    }
    
    public void addAtHead(int val) {
        // if (len == 0) {
        //     head = new ListNode(val);
        //     len++;
        //     return;
        // }
        // ListNode tmp = new ListNode(val);
        // tmp.next = head;
        // head = tmp;
        // len++;
        addAtIndex(0, val);
    }
    
    public void addAtTail(int val) {
        // if (len == 0) {
        //     addAtHead(val);
        //     return;
        // }
        // ListNode tmp = head;
        // while (tmp.next != null) tmp = tmp.next;
        // tmp.next = new ListNode(val);
        // len++;
        addAtIndex(len, val);
    }
    
    public void addAtIndex(int index, int val) {
        if (index > len || index < 0) return;
        // if (index == 0) {
        //     addAtHead(val);
        //     return;
        // }
        // if (index == len) {
        //     addAtTail(val);
        //     return;
        // }
        if (index == 0) {
            ListNode tmp = new ListNode(val);
            tmp.next = head;
            head = tmp;
            len++;
            return;
        }
        ListNode tmp = head;
        while (--index > 0) {
            tmp = tmp.next;
        }
        ListNode tmp2 = new ListNode(val);
        ListNode tmp3 = tmp.next;
        tmp.next = tmp2;
        tmp2.next = tmp3;
        len++;
    }
    
    public void deleteAtIndex(int index) {
        if (index < 0 || index >= len) return;
        if (index == 0) {
            head = head.next;
            len--;
            return;
        }
        ListNode tmp = head;
        while (--index > 0) {
            tmp = tmp.next;
        }

        tmp.next = tmp.next.next;
        len--;
    }
}


/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList obj = new MyLinkedList();
 * int param_1 = obj.get(index);
 * obj.addAtHead(val);
 * obj.addAtTail(val);
 * obj.addAtIndex(index,val);
 * obj.deleteAtIndex(index);
 */

 class ListNode {
     int val;
     ListNode next;

     public ListNode (int val) {
         this.val = val;
     }
 }

206. 反转链表 - 力扣(LeetCode)

/**
 * 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 reverseList(ListNode head) {
        if (head == null) return head;
        ListNode pre = head, cur = head.next, tmp = new ListNode();
        while (cur != null) {
            if (pre == head) pre.next = null;
            tmp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = tmp;
            
        }

        return pre;
    }
}

24. 两两交换链表中的节点 - 力扣(LeetCode)

/**
 * 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 swapPairs(ListNode head) {
        if (head == null) return head;
        ListNode pre = new ListNode(), dimmy = pre;
        pre.next = head;
        ListNode cur = head;
        ListNode tmp = cur.next;
        
        while (tmp != null) {
            pre.next = tmp;
            cur.next = tmp.next;
            tmp.next = cur;
            pre = cur;
            cur = cur.next;
            if (cur != null && cur.next != null)tmp = cur.next;
            else break;
        }

        return dimmy.next;
    }
}

19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)

/**
 * 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 removeNthFromEnd(ListNode head, int n) {
        
        ListNode cur = head;
        int len = 0;
        // 找到删除前的一个点
        while (cur != null) {
            cur = cur.next;
            len++;
        }
        if (n == len) {
            head = head.next;
            return head;
        }
        cur = head;
        int index = len - n;
        while (--index > 0) {
            cur = cur.next;
        }
        if (cur.next != null)cur.next = cur.next.next;
        else cur.next = null;

        return head;
    }
}

面试题 02.07. 链表相交 - 力扣(LeetCode)

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        int lenA = 0, lenB = 0;
        ListNode curA = headA, curB = headB;
        while(curA != null) {
            curA = curA.next;
            lenA++;
        }
        while(curB != null) {
            curB = curB.next;
            lenB++;
        }
        int diff = Math.abs(lenA - lenB);
        if (lenA < lenB) {
            curA = headB;
            curB = headA;
        } else {
            curA = headA;
            curB = headB;
        }
        while (diff > 0) {
            curA = curA.next;
            diff--;
        }

        while (curA != null) {
            if (curA == curB) return curA;
            curA = curA.next;
            curB = curB.next;
        }

        return null;
    }
}

142. 环形链表 II - 力扣(LeetCode)

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        if (head == null) return head;
        ListNode fast = head;
        ListNode low = head;
        while (low.next != null && fast != null && fast.next != null && fast.next.next != null) {
            low = low.next;
            fast = fast.next.next;
            if (low == fast) {
                ListNode tmp = head;
                while (low != tmp) {
                    low = low.next;
                    tmp = tmp.next;
                }
                return tmp;
            }
        }

        return null;
    }
}

哈希表

242. 有效的字母异位词 - 力扣(LeetCode)

class Solution {
    public boolean isAnagram(String s, String t) {
        int[] arr = new int[26];
        for (char c : s.toCharArray()) {
            arr[c - 'a'] += 1;
        }

        for (char c : t.toCharArray()) {
            arr[c - 'a']--;
        }

        for (int n : arr) {
            if (n != 0) return false;
        }

        return true;
    }
}

349. 两个数组的交集 - 力扣(LeetCode)

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        Map<Integer, Boolean> map = new HashMap<>();
        Set<Integer> set = new HashSet<>();
        for (int n : nums1) {
            map.put(n, true);
        }

        for (int n : nums2) {
            if (map.containsKey(n)) set.add(n);
        }

        return set.stream().mapToInt(x -> x).toArray();
    }
}

202. 快乐数 - 力扣(LeetCode)

class Solution {
    public boolean isHappy(int n) {
        Set<Integer> set = new HashSet<>();
        while (!set.contains(n)) {
            set.add(n);
            int sum = 0;
            while (n > 0) {
                sum += (n % 10) * (n % 10);
                n /= 10;
            }
            if (sum == 1) return true;
            n = sum;
        }

        return false;
    }
}

1. 两数之和 - 力扣(LeetCode)

class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> map = new HashMap<>();
        // 存target - nums[i], i
        for (int i = 0; i < nums.length; i++) {
            if (map.containsKey(nums[i])) {
                return new int[]{i, map.get(nums[i])};
            }
            map.put(target - nums[i], i);
        }

        return new int[]{0,0};
    }
}

454. 四数相加 II - 力扣(LeetCode)

class Solution {
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        Map<Integer, Integer> map = new HashMap<>();
        int res = 0;
        // 记录 sum, count 和 :次数
        for (int i = 0; i < nums1.length; i++) {
            for (int j = 0; j < nums2.length; j++) {
                map.put(nums1[i] + nums2[j], map.getOrDefault(nums1[i] + nums2[j], 0) + 1);
            }
        }

        for (int i = 0; i < nums3.length; i++) {
            for (int j = 0; j < nums4.length; j++) {
                if (map.containsKey(-nums3[i] - nums4[j])) res += map.get(-nums3[i] - nums4[j]);
            }
        }

        return res;
    }
}

383. 赎金信 - 力扣(LeetCode)

class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
        int[] arr = new int[26];
        for (char c : magazine.toCharArray()) {
            arr[c - 'a']++;
        }

        for (char c : ransomNote.toCharArray()) {
            arr[c - 'a']--;
            if (arr[c - 'a'] < 0) {
                return false;
            }
        }

        return true;
    }
}

15. 三数之和 - 力扣(LeetCode)双指针

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        Arrays.sort(nums);
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] > 0) return res;
            if (i > 0 && nums[i] == nums[i - 1]) continue;
            int l = i + 1;
            int r = nums.length - 1;
            while (l < r) {
                int sum = nums[i] + nums[l] + nums[r];
                if (sum < 0) l++;
                else if (sum > 0) r--;
                else {
                    res.add(Arrays.asList(nums[i], nums[l], nums[r]));
                    
                    while (r > l && nums[r] == nums[r - 1]) r--;
                    while (r > l && nums[l] == nums[l + 1]) l++;
					
                    r--;//到了没有重复之后,左右指针同时范围缩窄
                    l++;
                }
            }
        }

        return res;
    }
}

18. 四数之和 - 力扣(LeetCode)

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> res = new ArrayList<>();
        Arrays.sort(nums);
        for (int i = 0; i < nums.length; i++) {
            // if (nums[i] > target) return res; 如果这里用这个剪枝就是错误的
            if (i > 0 && nums[i] == nums[i - 1]) continue;
            for (int j = i + 1; j < nums.length; j++) {
                // if (nums[i] + nums[j] > target) return res;
                if (j > i + 1 && nums[j] == nums[j - 1]) continue;
                int l = j + 1;
                int r = nums.length - 1;
                while (l < r) {
                    long sum = (long)nums[i] + nums[l] + nums[r] + nums[j];
                    if (sum > target) r--;
                    else if (sum < target) l++;
                    else {
                        res.add(Arrays.asList(nums[i], nums[j], nums[l], nums[r]));
                        while (r > l && nums[r - 1] == nums[r]) r--;
                        while (r > l && nums[l + 1] == nums[l]) l++;
                        r--;
                        l++;
                    }
                }
            }
        }
        return res;
    }
}

字符串

344. 反转字符串 - 力扣(LeetCode)

class Solution {
    public void reverseString(char[] s) {
        int l = 0, r = s.length - 1;
        while (l < r) {
            char tmp = s[r];
            s[r--] = s[l];
            s[l++] = tmp;
        }
    }
}

541. 反转字符串 II - 力扣(LeetCode)

class Solution {
    public String reverseStr(String s, int k) {
        char[] arr = s.toCharArray();
        int i = 0;
        for (; i < s.length() / (2 * k) ; i++) {
            int l = i * 2 * k, r = i * 2 * k + k - 1;
            while (l < r) {
                char tmp = arr[l];
                arr[l++] = arr[r];
                arr[r--] = tmp;
            }
        }
        if (s.length() - (i * 2 * k) < k) {
            int l = i * 2 * k, r = s.length() - 1;
            while (l < r) {
                char tmp = arr[l];
                arr[l++] = arr[r];
                arr[r--] = tmp;
            }
        } else if (s.length() - (i * 2 * k) >= k && s.length() - (i * 2 * k) < 2 * k) {
            int l = i * 2 * k, r = i * 2 * k + k - 1;
            while (l < r) {
                char tmp = arr[l];
                arr[l++] = arr[r];
                arr[r--] = tmp;
            }
        }
        return new String(arr);
    }
}

剑指 Offer 05. 替换空格 - 力扣(LeetCode)

class Solution {
    public String replaceSpace(String s) {
        StringBuffer sb = new StringBuffer();
        for (char c : s.toCharArray()) {
            if (c == ' ') sb.append("%20");
            else sb.append(c);
        } 

        return sb.toString();
        
    }
}

151. 反转字符串中的单词 - 力扣(LeetCode)

class Solution {
    public String reverseWords(String s) {
        s = reverse(s.trim());
        StringBuffer sb = new StringBuffer();
        int low = 0, fast = 0;
        while (fast < s.length()) {
            low = fast;
            while(fast < s.length() && s.charAt(fast) != ' ')fast++; 
            sb.append(reverse(s.substring(low, fast)) + ' ');
            while (fast < s.length() && s.charAt(fast) == ' ')fast++;
        }
        
        sb.deleteCharAt(sb.length() - 1);
        return sb.toString();
    }

    public String reverse(String s) {
        int l = 0, r = s.length() - 1;
        char[] arr = s.toCharArray();
        while (l < r) {
            char c = arr[l];
            arr[l++] = arr[r];
            arr[r--] = c;
        }

        return new String(arr);
    }
}

剑指 Offer 58 - II. 左旋转字符串 - 力扣(LeetCode)

class Solution {
    public String reverseLeftWords(String s, int n) {
        char[] arr = s.toCharArray(), tmp = new char[n];
        // abcdefg cdefg + ab
        for (int i = 0; i < n; i++) {
            tmp[i] = arr[i];//i 0 1
        }
        for (int i = 0; i < arr.length - n; i++) {
            arr[i] = arr[i + n];
        }
        for (int i = arr.length - n, j = 0; i < arr.length; i++) {
            arr[i] = tmp[j++];
        }
        return new String(arr);
    }
}

28. 找出字符串中第一个匹配项的下标 - 力扣(LeetCode)

class Solution {
    public int strStr(String haystack, String needle) {
        
        for (int i = 0; i < haystack.length() - needle.length() + 1; i++) {
            if (haystack.charAt(i) == needle.charAt(0) && haystack.substring(i, i + needle.length()).equals(needle)) return i;
        }
        return -1;
    }

}

459. 重复的子字符串 - 力扣(LeetCode)

class Solution {
    public boolean repeatedSubstringPattern(String s) {
        String s1 = (s + s).substring(1, 2 * s.length() - 1);
        for (int i = 0; i < s1.length() - s.length() + 1; i++) {
            if (s1.substring(i, i + s.length()).equals(s)) return true;
        }

        return false;
    }
}

双指针法

27. 移除元素 - 力扣(LeetCode)

344. 反转字符串 - 力扣(LeetCode)

剑指 Offer 05. 替换空格 - 力扣(LeetCode)

151. 反转字符串中的单词 - 力扣(LeetCode)

206. 反转链表 - 力扣(LeetCode)

19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)

面试题 02.07. 链表相交 - 力扣(LeetCode)

三数之和

四数之和

栈与队列

232. 用栈实现队列 - 力扣(LeetCode)

class MyQueue {
    Stack<Integer> s1;
    Stack<Integer> s2;
    public MyQueue() {
        s1 = new Stack<>();
        s2 = new Stack<>();
    }
    
    public void push(int x) {
        s1.push(x);
    }
    
    public int pop() {
        if (!s2.isEmpty()) {
            return s2.pop();
        } else {
            while (!s1.isEmpty()) {
                s2.push(s1.pop());
            }
        }
        return s2.pop();
    }
    
    public int peek() {
        if (s2.isEmpty()) {
            while (!s1.isEmpty()) {
                s2.push(s1.pop());
            }
        }
        return s2.peek();
    }
    
    public boolean empty() {
        return s1.isEmpty() && s2.isEmpty();
    }
}

/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue obj = new MyQueue();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.peek();
 * boolean param_4 = obj.empty();
 */

225. 用队列实现栈 - 力扣(LeetCode)

class MyStack {
    LinkedList<Integer> q1;
    
    public MyStack() {
        q1 = new LinkedList<>();
        
    }
    
    public void push(int x) {
        q1.offer(x);
    }
    
    public int pop() {
        return q1.pollLast();
    }
    
    public int top() {
        return q1.peekLast();
    }
    
    public boolean empty() {    
        return q1.isEmpty();
    }
}

/**
 * Your MyStack object will be instantiated and called as such:
 * MyStack obj = new MyStack();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.top();
 * boolean param_4 = obj.empty();
 */

class MyStack {
    Queue<Integer> q1;
    Queue<Integer> q2;
    public MyStack() {
        q1 = new LinkedList<>();
        q2 = new LinkedList<>();
    }
    
    public void push(int x) {
        q1.offer(x);
    }
    
    public int pop() {
        while (q1.size() > 1) {
            q2.offer(q1.poll());
        }
        
        int res = q1.poll();
        Queue<Integer> tmp = q1;
        q1 = q2;
        q2 = tmp;

        return res;
    }
    
    public int top() {
        while (q1.size() > 1) {
            q2.offer(q1.poll());
        }
        
       

        return q1.peek();
    }
    
    public boolean empty() {    
        return q1.isEmpty();
    }
}

/**
 * Your MyStack object will be instantiated and called as such:
 * MyStack obj = new MyStack();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.top();
 * boolean param_4 = obj.empty();
 */

20. 有效的括号 - 力扣(LeetCode)

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

        return stack.isEmpty();
    }
}

1047. 删除字符串中的所有相邻重复项 - 力扣(LeetCode)

class Solution {
    public String removeDuplicates(String s) {
        Stack<Character> stack = new Stack<>();
        StringBuffer sb = new StringBuffer();
        for (char c : s.toCharArray()) {
            if (!stack.isEmpty()) {
                if (stack.peek() == c) {
                    stack.pop();
                    sb.deleteCharAt(sb.length() - 1);
                }
                else {
                    stack.push(c);
                    sb.append(c);
                }
            }
            else {
                stack.push(c);
                sb.append(c);
            }
        }
        return sb.toString();
        
    }
}

150. 逆波兰表达式求值 - 力扣(LeetCode)

class Solution {
    public int evalRPN(String[] tokens) {
        Stack<Integer> stack = new Stack<>();

        for (String s : tokens) {
            if (s.equals("+")) {
                int a = stack.pop();
                int b = stack.pop();
                stack.push(a + b);
            } else if (s.equals("-")) {
                int a = stack.pop();
                int b = stack.pop();
                stack.push(b - a);
            } else if (s.equals("*")) {
                int a = stack.pop();
                int b = stack.pop();
                stack.push(a * b);
            } else if (s.equals("/")) {
                int a = stack.pop();
                int b = stack.pop();
                stack.push(b / a);
            } else stack.push(Integer.parseInt(s));
        }

        return stack.pop();
    }
}

239. 滑动窗口最大值 - 力扣(LeetCode)

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        int[] res = new int[nums.length - k + 1];
        LinkedList<Integer> q = new LinkedList<>();
        for (int i = 0, j = 0; i < nums.length; i++) {
            if (!q.isEmpty() && i - k >= q.peek()) q.poll();
            while (!q.isEmpty() && nums[q.peekLast()] < nums[i]) q.pollLast();
            q.offer(i);
            if (i >= k - 1) res[j++] = nums[q.peek()];
        }

        return res;
    }
}

347. 前 K 个高频元素 - 力扣(LeetCode)

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        int res[] = new int[k];
        Map<Integer,Integer> map = new HashMap<>();
        for (int n : nums) {
            map.put(n, map.getOrDefault(n, 0) + 1);
        }
        PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> (b[1] - a[1]));
        for (Integer key : map.keySet()) {
            pq.offer(new int[]{key, map.get(key)});
        }

        for (int i = 0; i < k; i++) {
            res[i] = pq.poll()[0];
        }

        return res;
    }
}

二叉树

遍历

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    List<Integer> res;
    public List<Integer> preorderTraversal(TreeNode root) {
        res = new ArrayList<>();
        dfs(root);
        return res;
    }
    public void dfs(TreeNode root) {
        if (root == null) return;
        res.add(root.val);
        dfs(root.left);
        dfs(root.right);
    }
}

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    List<Integer> res;
    public List<Integer> postorderTraversal(TreeNode root) {
        res = new ArrayList<>();
        dfs(root);
        return res;
    }
    public void dfs(TreeNode root) {
        if (root == null) return;
        
        dfs(root.left);
    
        dfs(root.right);
        res.add(root.val);
    }
}

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    List<Integer> res;
    public List<Integer> inorderTraversal(TreeNode root) {
        res = new ArrayList<>();
        dfs(root);
        return res;
    }
    public void dfs(TreeNode root) {
        if (root == null) return;
        
        dfs(root.left);
        res.add(root.val);
        dfs(root.right);
        
    }
}

102. 二叉树的层序遍历 - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();

        if (root == null) return res;
        Queue<TreeNode> q = new LinkedList<>();
        q.add(root);
        while (!q.isEmpty()) {
            int len = q.size();
            List<Integer> tmp = new ArrayList();
            while(len > 0) {
                TreeNode node = q.poll();
                tmp.add(node.val);
                if (node.left != null) q.offer(node.left);
                if (node.right != null) q.offer(node.right);
                len--;
            }
            res.add(tmp);
        }

        return res;
    }
}

226. 翻转二叉树 - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode invertTree(TreeNode root) {
        if (root == null) return root;

        TreeNode tmp = root.left;
        root.left = invertTree(root.right);
        root.right = invertTree(tmp);


        return root;
    }

    // public TreeNode dfs(TreeNode root) {
        
    // }
}

101. 对称二叉树 - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isSymmetric(TreeNode root) {
        return check(root, root);
    }

    public boolean check(TreeNode right, TreeNode left) {
        if (right == null && left == null) return true;
        if (right == null && left != null) return false;
        if (right != null && left == null) return false;
        
        return right.val == left.val && check(right.right, left.left) && check(right.left, left.right);
    }
}

104. 二叉树的最大深度 - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int maxDepth(TreeNode root) {
        if (root == null) return 0;

        return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
    }
}

111. 二叉树的最小深度 - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int minDepth(TreeNode root) {
        if (root == null) return 0;
        
        int leftDepth = minDepth(root.left);
        int rightDepth = minDepth(root.right);

        if (root.left == null) return rightDepth + 1;
        if (root.right == null) return leftDepth + 1;

        return Math.min(leftDepth, rightDepth) + 1;
    }
}

222. 完全二叉树的节点个数 - 力扣(LeetCode)递归法

//层序遍历
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int countNodes(TreeNode root) {
        int res = 0;

        if (root == null) return res;
        Queue<TreeNode> q = new LinkedList<>();
        q.add(root);
        while (!q.isEmpty()) {
            int len = q.size();
            res += len;
            List<Integer> tmp = new ArrayList();
            while(len > 0) {
                TreeNode node = q.poll();
                tmp.add(node.val);
                if (node.left != null) q.offer(node.left);
                if (node.right != null) q.offer(node.right);
                len--;
            }
        }

        return res;
    }
}

// 递归法
class Solution {
    public int countNodes(TreeNode root) {
        if (root == null) return 0;
        return countNodes(root.left) + countNodes(root.right) + 1;
    }
}

110. 平衡二叉树 - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isBalanced(TreeNode root) {
         return dfs(root) != -1;
    }

    public int dfs(TreeNode root) {
        if (root == null) return 0;
        int leftDepth = dfs(root.left), rightDepth = dfs(root.right);
        
        if (leftDepth == -1) return -1;
        if (rightDepth == -1) return -1;
        if (Math.abs(leftDepth - rightDepth) > 1) {
            return -1;
        }

        return Math.max(leftDepth, rightDepth) + 1;
    }
}

257. 二叉树的所有路径 - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<String> binaryTreePaths(TreeNode root) {
        List<String> res = new ArrayList<>();
        Queue<TreeNode> q = new LinkedList<>();
        Queue<String> st = new LinkedList<>();
        q.offer(root);
        st.offer("" + root.val);
        while (!q.isEmpty()) {
            TreeNode node = q.poll();
            String s = st.poll();
            if (node.left != null) {
                st.offer(s + "->"+ node.left.val);
                q.offer(node.left);
            }
            if (node.right != null) {
                st.offer(s + "->" + node.right.val);
                q.offer(node.right);
            }
            if (node.left == null && node.right == null) {
                res.add(s);
            }
        }

        return res;
    }
}

404. 左叶子之和 - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int sumOfLeftLeaves(TreeNode root) {
        Queue<TreeNode> q = new LinkedList<>();
        int res = 0;
        q.offer(root);
        while (!q.isEmpty()) {
            TreeNode node = q.poll();
            if (node.left != null) {
                q.offer(node.left);
                if (node.left.left == null && node.left.right == null)res += node.left.val;
            }
            if (node.right != null) q.offer(node.right);
        }

        return res;
    }
}

513. 找树左下角的值 - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int findBottomLeftValue(TreeNode root) {
        Queue<TreeNode> q = new LinkedList<>();
        int res = root.val;
        q.offer(root);
        while (!q.isEmpty()) {
            int len = q.size();
            res = q.peek().val;
            while (len > 0) {
                TreeNode node = q.poll();
                if (node.left != null) q.offer(node.left);
                if (node.right != null) q.offer(node.right);
                len--;
            }
        }

        return res;
    }
}

112. 路径总和 - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    int sum = 0;
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if (root == null) return false;
        if (root.left == null && root.right == null) {
            if (sum + root.val == targetSum) return true;
            return false;
        }
        sum += root.val;
        boolean left = hasPathSum(root.left, targetSum);
        boolean right = hasPathSum(root.right, targetSum);
        sum -= root.val;

        return left || right;
    }
    
}

106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        if (postorder.length == 0) return null;
        TreeNode root = new TreeNode(postorder[postorder.length - 1]);
        int i = 0;
        while (i < inorder.length && inorder[i] != postorder[postorder.length - 1])i++;
        int len = i;
        root.left = buildTree(Arrays.copyOfRange(inorder, 0, len), Arrays.copyOfRange(postorder, 0, len));
        root.right = buildTree(Arrays.copyOfRange(inorder, len + 1, inorder.length), Arrays.copyOfRange(postorder, len, postorder.length - 1));

        return root;
    }
}

654. 最大二叉树 - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode constructMaximumBinaryTree(int[] nums) {
        return dfs(nums, 0, nums.length);
    }
    public TreeNode dfs(int[] nums, int start, int end) {
        if (end - start < 1) return null;
        if (end - start == 1) return new TreeNode(nums[start]);
        int max = nums[start];
        int index = start;
        for (int i = start + 1; i < end; i++) {
            if (nums[i] > max) {
                index = i;
                max = nums[i];
            }
        }
        TreeNode root = new TreeNode(max);
        root.left = dfs(nums, start, index);
        root.right = dfs(nums, index + 1, end);

        return root;
    }
}

617. 合并二叉树 - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if (root1 == null) return root2;
        if (root2 == null) return root1;
        
        root1.val += root2.val;
        root1.left = mergeTrees(root1.left, root2.left);
        root1.right = mergeTrees(root1.right, root2.right);

        return root1;
    }

    
}

700. 二叉搜索树中的搜索 - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode searchBST(TreeNode root, int val) {
        if (root == null) return root;
        if (val == root.val) return root;
        else if (val > root.val) return searchBST(root.right, val);

        return searchBST(root.left, val);
        
    }
}

98. 验证二叉搜索树 - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    LinkedList<Integer> q = new LinkedList<>();
    public boolean isValidBST(TreeNode root) {
        return dfs(root);
    }

    public boolean dfs(TreeNode root) {
        if (root == null) return true;

        boolean left = dfs(root.left);
        if (!left) return false;// 这一步非常神奇
        if (!q.isEmpty() && q.peekLast() >= root.val) return false;
        q.offer(root.val);
        

        return dfs(root.right);
    }
}

530. 二叉搜索树的最小绝对差 - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    int res = Integer.MAX_VALUE;
    TreeNode pre;
    public int getMinimumDifference(TreeNode root) {
        dfs(root);
        return res;
    }

    public void dfs(TreeNode root) {
        if (root == null) return;

        dfs(root.left);
        if (pre != null) res = Math.min(res, root.val - pre.val);
        pre = root;
        dfs(root.right);
    }
}

501. 二叉搜索树中的众数 - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> b[1] - a[1]);
    Map<Integer, Integer> map = new HashMap<>();
    List<Integer> res = new ArrayList<>();
    public int[] findMode(TreeNode root) {
        dfs(root);
        for (Integer n : map.keySet()) {
            pq.offer(new int[]{n, map.get(n)});
        }

        int max = pq.peek()[1];
        while (!pq.isEmpty() && pq.peek()[1] == max) {
            res.add(pq.poll()[0]);
        }

        return res.stream().mapToInt(x -> x).toArray();

    }

    public void dfs(TreeNode root) {
        if (root == null) return;

        dfs(root.left);
        map.put(root.val, map.getOrDefault(root.val, 0) + 1);
        dfs(root.right);
    }
}

236. 二叉树的最近公共祖先 - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null) return root;
        if (root == p) return p;
        if (root == q) return q;

        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);
        
        if (left != null && right != null) return root;
        else if (right == null && left != null) return left;
        else if (right != null && left == null) return right;
        return null;
    }
}

235. 二叉搜索树的最近公共祖先 - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == p || root == q || root == null) return root;
        if (root.val > p.val && root.val > q.val) return lowestCommonAncestor(root.left, p, q);
        if (root.val < p.val && root.val < q.val) return lowestCommonAncestor(root.right, p, q);


        return root;   
    }
}

701. 二叉搜索树中的插入操作 - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode insertIntoBST(TreeNode root, int val) {
        if (root == null) return new TreeNode(val);

        if (root.val > val) {
            root.left = insertIntoBST(root.left, val);
        } else if (root.val < val) {
            root.right = insertIntoBST(root.right, val);
        }

        return root;
    }
}

450. 删除二叉搜索树中的节点 - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
        if (root == null) return root;
        if (root.val == key) {
            if (root.left != null && root.right == null) {
                return root.left;
            } else if (root.left == null && root.right != null) {
                return root.right;
            } else if (root.left == null && root.right == null) {
                return null;
            } else if (root.left != null && root.right != null) {

                // 把左树放到右树最左端
                TreeNode cur = root.right;
                while (cur.left != null) {
                    cur = cur.left;
                }
                cur.left = root.left;
                root = root.right;
                return root; 
            }
        }

        if (root.val < key) root.right = deleteNode(root.right, key); 
        if (root.val > key) root.left = deleteNode(root.left, key);

        return root;
    }
}

669. 修剪二叉搜索树 - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode trimBST(TreeNode root, int low, int high) {
        if (root == null) return root;

        if (root.val < low) {
            return trimBST(root.right, low, high);
        } if (root.val > high) {
            return trimBST(root.left, low, high);
        }

        root.left = trimBST(root.left, low, high);
        root.right = trimBST(root.right, low, high);

        return root;
    }
}

108. 将有序数组转换为二叉搜索树 - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode sortedArrayToBST(int[] nums) {
        if (nums.length == 0) return null;
        int mid = (nums.length - 1) / 2;
        TreeNode root =  new TreeNode(nums[mid]);
        root.left = sortedArrayToBST(Arrays.copyOfRange(nums, 0, mid));
        root.right = sortedArrayToBST(Arrays.copyOfRange(nums, mid + 1, nums.length));

        return root;
    }
}

538. 把二叉搜索树转换为累加树 - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    int sum = 0;
    public TreeNode convertBST(TreeNode root) {
        dfs(root);

        return root;
    }
    public void dfs(TreeNode root) {
        if (root == null) return;

        dfs(root.right);
        
        sum += root.val;
        root.val = sum;
        dfs(root.left);
    }
}

回溯算法

77. 组合 - 力扣(LeetCode)★针对剪枝操作

class Solution {
    List<List<Integer>> res;
    LinkedList<Integer> tmp;
    public List<List<Integer>> combine(int n, int k) {
        res = new ArrayList<>();
        tmp = new LinkedList<>();
        dfs(n, 1, k);

        return res;
    }

    public void dfs(int n, int start, int k) {
        if (tmp.size() == k) {
            res.add(new ArrayList(tmp));
            return;
        }
        
        for (int i = start; i <= n - (k - tmp.size()) + 1; i++) {//剪枝操作
            tmp.add(i);
            dfs(n, i + 1, k);
            tmp.removeLast();
        }
    }
}

//非剪枝
class Solution {
    List<List<Integer>> res;
    LinkedList<Integer> tmp;
    public List<List<Integer>> combine(int n, int k) {
        res = new ArrayList<>();
        tmp = new LinkedList<>();
        dfs(n, 1, k);

        return res;
    }

    public void dfs(int n, int start, int k) {
        if (tmp.size() == k) {
            res.add(new ArrayList(tmp));
            return;
        }
        
        for (int i = start; i <= n; i++) {
            tmp.add(i);
            dfs(n, i + 1, k);
            tmp.removeLast();
        }
    }
}

216. 组合总和 III - 力扣(LeetCode)

剪枝细节

class Solution {
    List<List<Integer>> res;
    LinkedList<Integer> tmp;
    int sum;
    public List<List<Integer>> combinationSum3(int k, int n) {
        sum = 0;
        res = new ArrayList<>();
        tmp = new LinkedList<>();

        dfs(n, 1, k);

        return res;
    }

    public void dfs(int n, int start, int k) {
        if (sum > n) return;
        if (tmp.size() == k) {
            if (sum == n) {
                res.add(new ArrayList(tmp));
            }
            return;
        }
        
        for (int i = start; i <= 9; i++) {
            tmp.add(i);
            sum += i;
            dfs(n, i + 1, k);
            tmp.removeLast();
            sum -= i;
        }
    }

}

17. 电话号码的字母组合 - 力扣(LeetCode)

class Solution {
    List<String> res;
    StringBuffer sb;
    char[][] arr = new char[][]{{},{},{'a', 'b', 'c'}, {'d', 'e', 'f'}, {'g', 'h', 'i'}, {'j', 'k', 'l'},
        {'m', 'n', 'o'}, {'p', 'q', 'r', 's'}, {'t','u','v'}, {'w','x','y','z'}};
    public List<String> letterCombinations(String digits) {
        res = new ArrayList<>();
        if (digits.length() == 0) return res;
        sb = new StringBuffer();
        
        dfs(digits, 0);

        return res;
    }

    public void dfs(String digits, int start) {
        if (sb.length() >= digits.length()) {
            res.add(sb.toString());
            return;
        }

        for (int i = start; i < digits.length(); i++) {
            int x = digits.charAt(i) - '0';
            for (int j = 0; j < arr[x].length; j++) {
                sb.append(arr[x][j]);
                dfs(digits, i + 1);
                sb.deleteCharAt(sb.length() - 1);
            }
        }
    }


}

39. 组合总和 - 力扣(LeetCode)

class Solution {
    List<List<Integer>> res;
    LinkedList<Integer> path;
    int sum = 0;
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        res = new ArrayList<>();
        path = new LinkedList<>();
        Arrays.sort(candidates);
        dfs(candidates, target);

        return res;
    }

    public void dfs(int[] candidates, int target) {
        if (sum >= target) {
            if (sum == target) res.add(new ArrayList<>(path));
            return;
        }

        for (int i = 0; i < candidates.length; i++) {
            if (!path.isEmpty() && path.peekLast() > candidates[i]) continue;
            path.add(candidates[i]);
            sum += candidates[i];
            dfs(candidates, target);
            sum -= candidates[i];
            path.removeLast();
        }
    }
}

40. 组合总和 II - 力扣(LeetCode)

class Solution {
    List<List<Integer>> res;
    LinkedList<Integer> path;
    int sum;
    boolean[] used;
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        res = new ArrayList<>();
        path = new LinkedList<>();
        used = new boolean[candidates.length];
        Arrays.sort(candidates);
        sum = 0;
        dfs(candidates, target, 0);

        return res;
    }

    public void dfs(int[]candidates, int target, int start) {
        if (sum >= target) {
            if (sum == target) res.add(new ArrayList<>(path));
            return;
        }

        for (int i = start; i < candidates.length; i++) {
            if (i > 0 && candidates[i] == candidates[i - 1] && !used[i - 1]) continue;
            used[i] = true;
            path.add(candidates[i]);
            sum += candidates[i];
            dfs(candidates, target, i + 1);
            sum -= candidates[i];
            path.removeLast();
            used[i] = false;
        }
    }
}

78. 子集 - 力扣(LeetCode)

class Solution {
    List<List<Integer>> res;
    LinkedList<Integer> path;
    public List<List<Integer>> subsets(int[] nums) {
        res = new ArrayList<>();
        path = new LinkedList<>();

        dfs(nums, 0);

        return res;
    }

    public void dfs(int[] nums, int start) {
        res.add(new ArrayList<>(path));
        if (path.size() == nums.length) return;

        for (int i = start; i < nums.length; i++) {
            path.add(nums[i]);
            dfs(nums, i + 1);
            path.removeLast();
        }
    }
}

131. 分割回文串 - 力扣(LeetCode)

class Solution {
    List<List<String>> res;
    LinkedList<String> dq;
    public List<List<String>> partition(String s) {
        res = new ArrayList<>();
        dq = new LinkedList<>();
        dfs(s, 0);

        return res;
    }

    public void dfs(String s, int start) {
        if (start >= s.length()) {
            res.add(new ArrayList(dq));
        }
        for (int i = start; i < s.length(); i++) {
            if (isTrue(s, start, i)) {
                String str = s.substring(start, i + 1);
                dq.add(str);
            } else {
                continue;
            }

            dfs(s, i + 1);
            dq.removeLast();
        }
        
    }

    public boolean isTrue(String s, int i, int j) {
        while (i < j) {
            if (s.charAt(i++) != s.charAt(j--)) return false;
        }

        return true;
    }
}

93. 复原 IP 地址 - 力扣(LeetCode)

class Solution {
    List<String> res;
    public List<String> restoreIpAddresses(String s) {
        StringBuffer sb = new StringBuffer(s);
        res = new ArrayList();
        dfs(sb, 0, 0);

        return res;
    }

    public void dfs(StringBuffer sb, int start, int dots) {
        if (dots == 3) {
            if (isValid(sb, start, sb.length() - 1)) {
                res.add(sb.toString());
                return;
            }
        }

        for (int i = start; i < sb.length(); i++) {
            if (isValid(sb, start, i)) {
                sb.insert(i + 1, '.');
                dots++;
                dfs(sb, i + 2, dots);
                dots--;
                sb.deleteCharAt(i + 1);
            } else break;
        }
    }

    public boolean isValid(StringBuffer s, int i, int j) {
        if (i > j) return false;
        if (s.charAt(i) == '0' && i != j) return false;

        int num = 0;
        while(i <= j) {
            num = num * 10 + (s.charAt(i) - '0');
            if (num > 255) return false;
            i++;
        }

        return true;
    }
}

90. 子集 II - 力扣(LeetCode)

class Solution {
    List<List<Integer>> res;
    LinkedList<Integer> path;
    boolean[] used;
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        res = new ArrayList<>();
        used = new boolean[nums.length];
        path = new LinkedList<>();
        Arrays.sort(nums);
        dfs(nums, 0);

        return res;
    }

    public void dfs(int[] nums, int start) {
        
        res.add(new ArrayList<>(path));
        if (start == nums.length) return;
        

        for (int i = start; i < nums.length; i++) {
            if (i >= 1 && nums[i] == nums[i - 1] && !used[i - 1]) continue;
            path.add(nums[i]);
            used[i] = true;
            dfs(nums, i + 1);
            used[i] = false;
            path.removeLast();
        }
    }
}

491. 递增子序列 - 力扣(LeetCode)

class Solution {
    List<List<Integer>> res;
    LinkedList<Integer> path;
    boolean[] used;
    public List<List<Integer>> findSubsequences(int[] nums) {
        res = new ArrayList<>();
        used = new boolean[nums.length];
        path = new LinkedList<>();
        dfs(nums, 0);

        return res;
    }
    public void dfs(int[] nums, int start) {
        if (path.size() >= 2) {
            res.add(new ArrayList<>(path));
            if (start == nums.length) return;
        }
        
        for (int i = start; i < nums.length; i++) {
            if (!path.isEmpty() && path.peekLast() > nums[i]) continue;
            
            if (i > 0) {
                int j = start;
                boolean flag = false;
                while (j < i) {
                    if (nums[i] == nums[j] && !used[j]) {
                        flag = true;
                        break;
                    }
                    j++;
                }
                if(flag) continue;
            }
            used[i] = true;
            path.add(nums[i]);
            dfs(nums, i + 1);
            path.removeLast();
            used[i] = false;
        }
    }
}

// 最快
class Solution {
    private List<Integer> path = new ArrayList<>();
    private List<List<Integer>> res = new ArrayList<>();
    public List<List<Integer>> findSubsequences(int[] nums) {
        backtracking(nums,0);
        return res;
    }

    private void backtracking (int[] nums, int start) {
        if (path.size() > 1) {
            res.add(new ArrayList<>(path));
        }

        int[] used = new int[201];
        for (int i = start; i < nums.length; i++) {
            if (!path.isEmpty() && nums[i] < path.get(path.size() - 1) ||
                    (used[nums[i] + 100] == 1)) continue;
            used[nums[i] + 100] = 1;
            path.add(nums[i]);
            backtracking(nums, i + 1);
            path.remove(path.size() - 1);
        }
    }
}

46. 全排列 - 力扣(LeetCode)

class Solution {
    List<List<Integer>> res;
    LinkedList<Integer> path;
    boolean[] used;
    public List<List<Integer>> permute(int[] nums) {
        res = new ArrayList<>();
        path = new LinkedList<>();
        used = new boolean[nums.length];
        backtracking(nums);

        return res;
    }

    public void backtracking(int[] nums) {
        if (path.size() == nums.length) {
            res.add(new ArrayList<>(path));
        }

        for (int i = 0; i < nums.length; i++) {
            if (used[i]) continue;
            used[i] = true;
            path.add(nums[i]);
            backtracking(nums);
            used[i] = false;
            path.removeLast();
            
        }
    }
}

47. 全排列 II - 力扣(LeetCode)

class Solution {
    List<List<Integer>> res;
    LinkedList<Integer> path;
    boolean[] used;
    public List<List<Integer>> permuteUnique(int[] nums) {
        res = new ArrayList<>();
        path = new LinkedList<>();
        used = new boolean[nums.length];
        Arrays.sort(nums);
        backtracking(nums);

        return res;
    }
    
    public void backtracking(int[] nums) {
        if (path.size() == nums.length) {
            res.add(new ArrayList<>(path));
        }

        for (int i = 0; i < nums.length; i++) {
            if (i > 0 && !used[i - 1] && nums[i] == nums[i - 1]) continue;
            if (used[i]) continue;
            used[i] = true;
            path.add(nums[i]);
            backtracking(nums);
            used[i] = false;
            path.removeLast();
            
        }
    }

}

332. 重新安排行程 - 力扣(LeetCode)

class Solution {
    LinkedList<String> res;
    LinkedList<String> path;
    boolean[] used;
    public List<String> findItinerary(List<List<String>> tickets) {
        Collections.sort(tickets, (a, b) -> a.get(1).compareTo(b.get(1)));
        res = new LinkedList<>();
        path = new LinkedList<>();
        used = new boolean[tickets.size()];
        path.add("JFK");
        backtracking((ArrayList) tickets);

        return res; 
    }
    
    public boolean backtracking(ArrayList<List<String>> tickets) {
        if (path.size() == tickets.size() + 1) {
            res = new LinkedList<>(path);
            return true;
        }

        for (int i = 0;  i < tickets.size(); i++) {
            if (!used[i] && tickets.get(i).get(0).equals(path.getLast())) {
                path.add(tickets.get(i).get(1));
                used[i] = true;
                if (backtracking(tickets)) {
                    return true;
                }
                used[i] = false;
                path.removeLast();
            }  
        }
        return false;
    }
}

332. 重新安排行程 - 力扣(LeetCode)

class Solution {
    LinkedList<String> res;
    LinkedList<String> path;
    boolean[] used;
    public List<String> findItinerary(List<List<String>> tickets) {
        Collections.sort(tickets, (a, b) -> a.get(1).compareTo(b.get(1)));
        res = new LinkedList<>();
        path = new LinkedList<>();
        used = new boolean[tickets.size()];
        path.add("JFK");
        backtracking((ArrayList) tickets);

        return res; 
    }
    
    public boolean backtracking(ArrayList<List<String>> tickets) {
        if (path.size() == tickets.size() + 1) {
            res = new LinkedList<>(path);
            return true;
        }

        for (int i = 0;  i < tickets.size(); i++) {
            if (!used[i] && tickets.get(i).get(0).equals(path.getLast())) {
                path.add(tickets.get(i).get(1));
                used[i] = true;
                if (backtracking(tickets)) {
                    return true;
                }
                used[i] = false;
                path.removeLast();
            }  
        }
        return false;
    }
}

51. N 皇后 - 力扣(LeetCode)

class Solution {
    char[][] map;
    LinkedList<String> tmp = new LinkedList<>();
    List<List<String>> res = new ArrayList<>();
    public List<List<String>> solveNQueens(int n) {
        map = new char[n][n];
        for(int i = 0; i < n; i++) Arrays.fill(map[i], '.');
        
        backTracking(map, 0);

        return res;
    }

    public void backTracking (char[][] map, int x) {
        if (x == map.length) {
            res.add(new ArrayList<>(tmp));
            return;
        }
        for (int i = x, j = 0; j < map.length; j++) {
            if (isValid(map, map.length, i, j)) {
                map[i][j] = 'Q';
                tmp.add(new String(map[i]));
                backTracking(map, i + 1);
                tmp.removeLast();
                map[i][j] = '.';
            }
        }

    }

    public boolean isValid(char[][] map, int n, int x, int y) {
        for (int i = 0; i < x; i++) {
            if (map[i][y] == 'Q') return false;
        }
        for (int i = x - 1, j = y - 1; i >= 0 && j >= 0; i--, j--) {
            if (map[i][j] == 'Q') return false;
        }
        for (int i = x - 1, j = y + 1; i >= 0 && j < n; i--, j++) {
            if (map[i][j] == 'Q') return false;
        }

        return true;
    }
}

37. 解数独 - 力扣(LeetCode)

class Solution {
    public void solveSudoku(char[][] board) {
        dfs (board);
    }

    public boolean dfs(char[][]board) {
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                if (board[i][j] != '.') continue;
                for (char c = '1'; c <= '9'; c++) {
                    if (isValid(board, i, j, c)) {
                        board[i][j] = c;

                        if (dfs(board)) return true;
                        board[i][j] = '.';
                    }
                }
                return false;
            }
        }
        return true;
    }

    public boolean isValid(char[][] board, int x, int y, char n) {
        for (int i = 0; i < 9; i++) {
            if (n == board[i][y]) return false;
        }
        for (int i = 0; i < 9; i++) {
            if (n == board[x][i]) return false;
        }
        int i = x / 3 * 3, j = y / 3 * 3;
        for (int k = i; k < i + 3; k++) {
            for (int l = j; l < j + 3; l++) {
                if (board[k][l] == n) return false;
            }
        }

        return true;
    }
}

动态规划

509. 斐波那契数 - 力扣(LeetCode)

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

        return dp[2];
    }
}

70. 爬楼梯 - 力扣(LeetCode)

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

        return dp[n];
    }
}

746. 使用最小花费爬楼梯 - 力扣(LeetCode)

class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int[] dp = new int[cost.length + 3];

        for (int i = 2; i < dp.length - 1; i++) {
            dp[i] = Math.min(dp[i - 1], dp[i - 2]) + cost[i - 2];
        }
        dp[dp.length - 1] = Math.min(dp[dp.length - 2], dp[dp.length - 3]);
        return dp[dp.length - 1];
    }
}

62. 不同路径 - 力扣(LeetCode)

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

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

63. 不同路径 II - 力扣(LeetCode)

class Solution {
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        int[][] dp = new int[obstacleGrid.length][obstacleGrid[0].length];

        for (int i = 0; i < dp.length; i++) {
            if (obstacleGrid[i][0] == 0) dp[i][0] = 1;
            else break;
        }
        for (int j = 0; j < dp[0].length; j++) {
            if (obstacleGrid[0][j] == 0) dp[0][j] = 1;
            else break;
        }

        for (int i = 1; i < dp.length; i++) {
            for (int j = 1; j < dp[0].length; j++) {
                if (obstacleGrid[i][j] == 1) continue;
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
            }
        }

        return dp[dp.length - 1][dp[0].length - 1];
    }
}

343. 整数拆分 - 力扣(LeetCode)

class Solution {
    public int integerBreak(int n) {
        if (n == 2) return 1;
        if (n == 3) return 2;
        if (n == 4) return 4;
        long res = 1;
        while (n > 4) {
            res *= 3;
            n -= 3;
        }

        res *= n;

        return (int)res;
    }
}

★ 特殊题 96. 不同的二叉搜索树 - 力扣(LeetCode)

class Solution {
    public int numTrees(int n) {
    // 1.dp[i] = a 代表i个数可以组成a种互不相同的二叉搜索树
    /**dp[3],就是 元素1为头结点搜索树的数量 + 元素2为头结点搜索树的数量 + 元素3为头结点搜索树的数量
    元素1为头结点搜索树的数量 = 右子树有2个元素的搜索树数量 * 左子树有0个元素的搜索树数量
    元素2为头结点搜索树的数量 = 右子树有1个元素的搜索树数量 * 左子树有1个元素的搜索树数量
    元素3为头结点搜索树的数量 = 右子树有0个元素的搜索树数量 * 左子树有2个元素的搜索树
    数量有2个元素的搜索树数量就是dp[2]。
    有1个元素的搜索树数量就是dp[1]。
    有0个元素的搜索树数量就是dp[0]。 */
    //2. dp[i] += dp[j - 1] * dp[i - j]
    //3.初始条件dp[0] = 1 空树也是一种搜索树
    //4.从前往后
    //5.
    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];
    }
}

416. 分割等和子集 - 力扣(LeetCode)

class Solution {
    public boolean canPartition(int[] nums) {
        int sum = 0;
        for (int n : nums) {
            sum += n;
        }
        if (sum % 2 == 1) return false;
        boolean[][] dp = new boolean[nums.length][sum / 2 + 1];
        if (nums[0] <= sum / 2) dp[0][nums[0]] = true;

        for (int i = 1; i < nums.length; i++) {
            for (int j = 0; j < dp[0].length; j++) {
                dp[i][j] = dp[i - 1][j];
                if (j == nums[i]) {
                    dp[i][j] = true;
                    continue;
                }
                if (j > nums[i]) {
                    dp[i][j] = dp[i - 1][j - nums[i]] || dp[i - 1][j];
                }
            }
        }

        return dp[dp.length - 1][dp[0].length -1];
    }
}

★[1049. 最后一块石头的重量 II - 力扣(LeetCode)

class Solution {
    public int lastStoneWeightII(int[] stones) {
        int sum = 0;
        for (int n : stones) {
            sum += n;
        }

        int target = sum / 2;
        int max = 0;
        boolean[][] dp = new boolean[stones.length][target + 1];
        if (stones[0] < dp[0].length) dp[0][stones[0]] = true;
        dp[0][0] = true;
        for (int i = 1; i < dp.length; i++) {
            for (int j = 0; j < dp[0].length; j++) {
                dp[i][j] = dp[i - 1][j];
                if (j >= stones[i]) {
                    dp[i][j] = dp[i - 1][j - stones[i]] || dp[i - 1][j];
                }
                if (dp[i][j]) max = Math.max(max, j);  
            }
        }

        return sum - max * 2;
    }
}

  • 21
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值