1. 两数之和
1. 两数之和
class Solution {
public int[] twoSum(int[] nums, int target) {
int n = nums.length;
int[] ans = new int[2];
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (nums[i] + nums[j] == target) {
ans[0] = i;
ans[1] = j;
return ans;
}
}
}
return ans;
}
}
49. 字母异位词分组
49. 字母异位词分组
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
Map<String, List<String>> map = new HashMap<>();
for(String str : strs) {
char[] ch = str.toCharArray();
Arrays.sort(ch);
map.computeIfAbsent(new String(ch), key -> new ArrayList<>()).add(str);
}
List<List<String>> ans = new ArrayList<>();
map.forEach((k,v)-> {
ans.add(v);
});
return ans;
}
}
128. 最长连续序列
128. 最长连续序列
class Solution {
public int longestConsecutive(int[] nums) {
Set<Integer> set = new HashSet<>();
for (int num : nums) {
set.add(num);
}
int ans = 0;
for (int num : nums) {
if (set.contains(num) && !set.contains(num - 1)) {
int y = num;
while (set.contains(y)) {
set.remove(y);
y++;
}
ans = Math.max(ans, y - num);
}
}
return ans;
}
}
283. 移动零
283. 移动零
class Solution {
public void moveZeroes(int[] nums) {
int n = nums.length;
int l = 0 , r = 0;
while(r < n) {
if(nums[r] != 0) {
swap(nums, l, r);
l++;
}
r++;
}
}
public void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
11. 盛最多水的容器
11. 盛最多水的容器
class Solution {
public int maxArea(int[] height) {
int n = height.length;
int l = 0, r = n - 1;
int ans = 0;
while(l < r) {
ans = Math.max(ans, (r - l) * Math.min(height[l], height[r]));
if(height[l] > height[r]){
r--;
} else {
l++;
}
}
return ans;
}
}
15. 三数之和
15. 三数之和
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> ans = new ArrayList<>();
int n = nums.length;
if(n == 0) return ans;
Arrays.sort(nums);
for(int i = 0; i < n; i ++) {
if(i > 0 && nums[i] == nums[i-1]) {
continue;
}
int target = -nums[i];
int k = n - 1;
for(int j = i + 1; j < k ;j ++) {
if(j > i + 1 && nums[j] == nums[j - 1]) {
continue;
}
while(j < k && nums[j] + nums[k] > target) {
k--;
}
if(j == k) break;
if(nums[j] + nums[k] == target) {
List<Integer> temp = new ArrayList<>();
temp.add(nums[i]);
temp.add(nums[j]);
temp.add(nums[k]);
ans.add(temp);
}
}
}
return ans;
}
}
42. 接雨水
42. 接雨水
class Solution {
public int trap(int[] height) {
Deque<Integer> dq = new ArrayDeque<>();
int n = height.length;
int ans = 0;
for(int i = 0; i < n; i ++) {
while(!dq.isEmpty() && height[dq.peekLast()] < height[i]) {
int top = dq.pollLast();
if(dq.isEmpty()) break;
ans += (i - dq.peekLast() - 1) * (Math.min(height[i], height[dq.peekLast()]) - height[top]);
}
dq.offerLast(i);
}
return ans;
}
}
3. 无重复字符的最长子串
3. 无重复字符的最长子串
class Solution {
public int lengthOfLongestSubstring(String s) {
Set<Character> set = new HashSet<>();
int n = s.length();
int r = 0, ans = 0;
for(int l = 0; l < n; l ++) {
if(l != 0) {
set.remove(s.charAt(l - 1));
}
while(r < n && !set.contains(s.charAt(r))) {
set.add(s.charAt(r));
r++;
}
ans = Math.max(ans, r - l);
}
return ans;
}
}
438. 找到字符串中所有字母异位词
438. 找到字符串中所有字母异位词
class Solution {
public List<Integer> findAnagrams(String s, String p) {
int n = s.length();
int m = p.length();
List<Integer> ans = new ArrayList<>();
if (n < m) {
return ans;
}
int[] sCnt = new int[26];
int[] pCnt = new int[26];
for (int i = 0; i < m; i++) {
sCnt[s.charAt(i) - 'a']++;
pCnt[p.charAt(i) - 'a']++;
}
if (Arrays.equals(sCnt, pCnt)) {
ans.add(0);
}
for (int i = 0; i < n - m; i++) {
sCnt[s.charAt(i) - 'a']--;
sCnt[s.charAt(i + m) - 'a']++;
if (Arrays.equals(sCnt, pCnt)) {
ans.add(i + 1);
}
}
return ans;
}
}
560. 和为 K 的子数组
560. 和为 K 的子数组
class Solution {
public int subarraySum(int[] nums, int k) {
int n = nums.length;
Map<Integer, Integer> map = new HashMap<>();
int pre = 0;
int ans = 0;
map.put(0,1);
for (int i = 0; i < n; i++) {
pre += nums[i];
if (map.containsKey(pre - k)) {
ans += map.get(pre - k);
}
map.put(pre, map.getOrDefault(pre, 0) + 1);
}
return ans;
}
}
239. 滑动窗口最大值
239. 滑动窗口最大值
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
int n = nums.length;
int[] ans = new int[n - k + 1];
Deque<Integer> dq = new ArrayDeque<>();
for (int i = 0; i < k; i++) {
while (!dq.isEmpty() && nums[i] >= nums[dq.peekLast()]) {
dq.pollLast();
}
dq.offerLast(i);
}
ans[0] = nums[dq.peekFirst()];
for (int i = k; i < n; i++) {
while (!dq.isEmpty() && nums[i] >= nums[dq.peekLast()]) {
dq.pollLast();
}
dq.offerLast(i);
if (i - dq.peekFirst() >= k) {
dq.pollFirst();
}
ans[i - k + 1] = nums[dq.peekFirst()];
}
return ans;
}
}
76. 最小覆盖子串
76. 最小覆盖子串
class Solution {
public String minWindow(String s, String t) {
int[] sCnt = new int[60];
int[] tCnt = new int[60];
int n = s.length();
int m = t.length();
if(m > n) {
return "";
}
for(int i = 0; i < m; i++) {
tCnt[t.charAt(i) - 'A'] ++;
}
int left = 0, right = 0;
int len = Integer.MAX_VALUE;
int l = 0, r = 0;
while(right < n) {
sCnt[s.charAt(right) - 'A']++;
right++;
while (check(sCnt, tCnt)) {
if (len > right - left) {
l = left;
r = right;
len = r - l;
}
sCnt[s.charAt(left) - 'A']--;
left++;
}
}
return s.substring(l, r);
}
boolean check(int[] sCnt, int[] tCnt) {
for (int i = 0; i < 60; i++) {
if (sCnt[i] < tCnt[i]) {
return false;
}
}
return true;
}
}
53. 最大子数组和
53. 最大子数组和
class Solution {
public int maxSubArray(int[] nums) {
int ans = Integer.MIN_VALUE;
int last = 0;
for(int i = 0; i < nums.length; i ++) {
last = nums[i] + Math.max(last, 0);
ans = Math.max(ans, last);
}
return ans;
}
}
56. 合并区间
56. 合并区间
class Solution {
public int[][] merge(int[][] intervals) {
int len = intervals.length;
if(len == 0) {
return new int[0][0];
}
Arrays.sort(intervals, (o1,o2)-> o1[0] - o2[0]);
List<int[]> list = new ArrayList<>();
int l = intervals[0][0] , r = intervals[0][1];
for(int i = 1; i < len; i ++) {
if(intervals[i][0] <= r) {
r = Math.max(r, intervals[i][1]);
} else {
list.add(new int[]{l , r});
l = intervals[i][0];
r = intervals[i][1];
}
}
list.add(new int[]{l , r});
int[][] ans = new int[list.size()][2];
for(int i = 0; i < list.size(); i ++) {
ans[i] = list.get(i);
}
return ans;
}
}
189. 轮转数组
189. 轮转数组
class Solution {
public void rotate(int[] nums, int k) {
int len = nums.length;
k = k % len;
reverse(nums, 0, len - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, len - 1);
}
public void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
public void reverse(int[] nums, int l, int r) {
while(l < r) {
swap(nums, l, r);
l ++;
r --;
}
}
}
238. 除自身以外数组的乘积
238. 除自身以外数组的乘积
class Solution {
public int[] productExceptSelf(int[] nums) {
int len = nums.length;
int[] ans = new int[len];
ans[0] = 1;
for(int i = 1; i < len; i ++) {
ans[i] = ans[i - 1] * nums[i - 1];
}
int r = 1;
for(int i = len - 1; i >= 0; i --) {
ans[i] = ans[i] * r;
r *= nums[i];
}
return ans;
}
}
41. 缺失的第一个正数
41. 缺失的第一个正数
class Solution {
public int firstMissingPositive(int[] nums) {
int n = nums.length;
for(int i = 0; i < n; i ++) {
if(nums[i] != Integer.MIN_VALUE) {
nums[i] --;
}
}
for(int i = 0; i < n; i ++) {
while(nums[i] >= 0 && nums[i] < n && nums[i] != nums[nums[i]]) {
swap(nums, i, nums[i]);
}
}
for(int i = 0; i < n; i ++) {
if(nums[i] != i) {
return i + 1;
}
}
return n + 1;
}
public void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
73. 矩阵置零
73. 矩阵置零
class Solution {
public void setZeroes(int[][] matrix) {
int n = matrix.length;
int m = matrix[0].length;
boolean[] row = new boolean[n];
boolean[] col = new boolean[m];
for(int i = 0; i < n; i ++) {
for(int j = 0; j < m; j ++) {
if(matrix[i][j] == 0) {
row[i] = col[j] = true;
}
}
}
for(int i = 0; i < n; i ++) {
for(int j = 0; j < m; j++) {
if(row[i] || col[j]) {
matrix[i][j] = 0;
}
}
}
}
}
54. 螺旋矩阵
54. 螺旋矩阵
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> ans = new ArrayList<>();
int n = matrix.length;
int m = matrix[0].length;
boolean[][] f = new boolean[n][m];
int[] dx = new int[] { 0, 1, 0, -1 };
int[] dy = new int[] { 1, 0, -1, 0 };
int x = 0, y = 0;
int k = 0;
f[x][y] = true;
for (int i = 0; i < n * m; i++) {
ans.add(matrix[x][y]);
f[x][y] = true;
int nx = dx[k] + x;
int ny = dy[k] + y;
if (nx < 0 || nx >= n || ny < 0 || ny >= m || f[nx][ny]) {
k++;
k = k % 4;
}
x = dx[k] + x;
y = dy[k] + y;
}
return ans;
}
}
48. 旋转图像
48. 旋转图像
class Solution {
public void rotate(int[][] matrix) {
int n = matrix.length;
for(int i = 0; i < n; i ++) {
for(int j = 0; j < i; j ++) {
swap(matrix, i, j, j, i);
}
}
for(int i = 0; i < n; i ++) {
for(int j = 0; j * 2 < n ; j ++) {
swap(matrix, i, j,i,n-j - 1);
}
}
}
public void swap(int[][] mat, int x1, int y1, int x2, int y2) {
int temp = mat[x1][y1];
mat[x1][y1] = mat[x2][y2];
mat[x2][y2] = temp;
}
}
240. 搜索二维矩阵 II
240. 搜索二维矩阵 II
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int m = matrix.length;
int n = matrix[0].length;
int i = 0, j = n - 1;
while (i < m && j >= 0) {
if(matrix[i][j] == target) {
return true;
}
if(matrix[i][j] > target) {
j --;
} else {
i ++;
}
}
return false;
}
}
160. 相交链表
160. 相交链表
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA == null || headB == null) return null;
ListNode l1 = headA;
ListNode l2 = headB;
while (l1 != l2) {
l1 = l1 == null ? headB : l1.next;
l2 = l2 == null ? headA : l2.next;
}
return l1;
}
}
206. 反转链表
206. 反转链表
class Solution {
public ListNode reverseList(ListNode head) {
if(head == null) return head;
ListNode h1 = null;
while(head != null) {
ListNode next = head.next;
head.next = h1;
h1 = head;
head = next;
}
return h1;
}
}
234. 回文链表
234. 回文链表
class Solution {
public boolean isPalindrome(ListNode head) {
if(head == null) return true;
ListNode l1 = half(head);
ListNode l2 = reverse(l1.next);
ListNode h1 = head;
ListNode h2 = l2;
boolean ans = true;
while(ans && h1 != null && h2 != null) {
if(h1.val != h2.val) {
ans = false;
break;
}
h1 = h1.next;
h2 = h2.next;
}
l1.next = reverse(l2);
return ans;
}
public ListNode half(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while(fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
public ListNode reverse (ListNode head) {
ListNode h1 = null;
while(head != null) {
ListNode next = head.next;
head.next = h1;
h1 = head;
head = next;
}
return h1;
}
}
141. 环形链表
141. 环形链表
public class Solution {
public boolean hasCycle(ListNode head) {
if(head == null) return false;
ListNode fast = head;
ListNode slow = head;
while(fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
if(fast == slow) {
return true;
}
}
return false;
}
}
142. 环形链表 II
142. 环形链表 II
public class Solution {
public ListNode detectCycle(ListNode head) {
if(head == null) return head;
ListNode fast = head;
ListNode slow = head;
while(fast.next != null) {
slow = slow.next;
if(fast.next.next != null) {
fast = fast.next.next;
} else {
return null;
}
if(fast == slow) {
ListNode ptr = head;
while(ptr != fast) {
ptr = ptr.next;
fast = fast.next;
}
return fast;
}
}
return null;
}
}
21. 合并两个有序链表
21. 合并两个有序链表
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
ListNode l1 = list1;
ListNode l2 = list2;
ListNode h = new ListNode(-1);
ListNode ans = h;
while(l1 != null && l2 != null ) {
if(l1.val <= l2.val) {
h.next = l1;
l1 = l1.next;
} else {
h.next = l2;
l2 = l2.next;
}
h = h.next;
h.next = null;
}
while(l1 != null) {
h.next = l1;
l1 = l1.next;
h = h.next;
h.next = null;
}
while(l2 != null) {
h.next = l2;
l2 = l2.next;
h = h.next;
h.next = null;
}
return ans.next;
}
}
2. 两数相加
2. 两数相加
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode node = new ListNode(0);
ListNode head = node;
int carry = 0;
while(l1 != null || l2 != null) {
int a = l1 == null ? 0 : l1.val;
int b = l2 == null ? 0 : l2.val;
int sum = a + b + carry;
ListNode temp = new ListNode(sum % 10);
head.next = temp;
head = temp;
carry = sum / 10;
if(l1 != null) l1 = l1.next;
if(l2 != null) l2 = l2.next;
}
if(carry > 0) {
ListNode temp = new ListNode(carry);
head.next = temp;
head = temp;
}
return node.next;
}
}
19. 删除链表的倒数第 N 个结点
19. 删除链表的倒数第 N 个结点
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode pre = new ListNode(-1);
pre.next = head;
ListNode h1 = pre;
ListNode h2 = head;
while(n-- > 0) {
h2 = h2.next;
}
while(h2 != null) {
h2 = h2.next;
h1 = h1.next;
}
h1.next = h1.next.next;
return pre.next;
}
}
24. 两两交换链表中的节点
24. 两两交换链表中的节点
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode ans = new ListNode(-1);
ans.next = head;
ListNode l1 = ans;
while(l1.next != null && l1.next.next != null) {
ListNode node1 = l1.next;
ListNode node2 = l1.next.next;
l1.next = node2;
node1.next = node2.next;
node2.next = node1;
l1 = node1;
}
return ans.next;
}
}
25. K 个一组翻转链表
25. K 个一组翻转链表
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
ListNode ans = new ListNode(-1);
ListNode pre = ans;
pre.next = head;
while(head != null) {
ListNode tail = pre;
for(int i = 0; i < k; i ++) {
tail = tail.next;
if(tail == null) {
return ans.next;
}
}
ListNode nextGroupHead = tail.next;
ListNode[] ls = reverse(head, tail);
head = ls[0];
tail = ls[1];
tail.next = nextGroupHead;
pre.next = head;
pre = tail;
head = nextGroupHead;
}
return ans.next;
}
public ListNode[] reverse(ListNode head, ListNode tail) {
ListNode pre = tail.next;
ListNode l1 = head;
while(tail != pre) {
ListNode next = l1.next;
l1.next = pre;
pre = l1;
l1 = next;
}
return new ListNode[] {tail, head};
}
}
138. 随机链表的复制
138. 随机链表的复制
class Solution {
public Node copyRandomList(Node head) {
Map<Node,Node> map = new HashMap<>();
Node cur = head;
while(cur != null) {
map.put(cur, new Node(cur.val));
cur = cur.next;
}
map.forEach((k,v)-> {
v.next = map.get(k.next);
v.random = map.get(k.random);
});
return map.get(head);
}
}
148. 排序链表
148. 排序链表
class Solution {
public ListNode sortList(ListNode head) {
if(head == null) return head;
ListNode dummpy = new ListNode(-1);
dummpy.next = head;
ListNode sort = head;
ListNode cur = sort.next;
while(cur != null) {
if(sort.val <= cur.val) {
sort = sort.next;
} else {
ListNode pre = dummpy;
while(pre.next.val <= cur.val) {
pre = pre.next;
}
sort.next = cur.next;
cur.next = pre.next;
pre.next = cur;
}
cur = sort.next;
}
return dummpy.next;
}
}
23. 合并 K 个升序链表
23. 合并 K 个升序链表
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
PriorityQueue<ListNode> pq = new PriorityQueue<>((o1,o2)-> o1.val - o2.val);
for(ListNode node : lists) {
if(node != null)
pq.offer(node);
}
ListNode dummpy = new ListNode(-1);
ListNode cur = dummpy;
while(!pq.isEmpty()) {
ListNode temp = pq.poll();
cur.next = temp;
cur = temp;
if(temp.next != null) pq.offer(temp.next);
}
return dummpy.next;
}
}
146. LRU 缓存
146. LRU 缓存
class LRUCache {
Map<Integer, Node> map;
Node left;
Node right;
int n;
public class Node {
Integer key;
Integer value;
Node left;
Node right;
public Node() {
}
public Node(int key, int val) {
this.value = val;
this.key = key;
}
}
public LRUCache(int capacity) {
map = new HashMap<>();
left = new Node();
right = new Node();
left.right = right;
right.left = left;
n = capacity;
}
public void remove(Node node) {
node.left.right = node.right;
node.right.left = node.left;
}
public void insert(Node node) {
left.right.left = node;
node.right = left.right;
left.right = node;
node.left = left;
map.put(node.key, node);
}
public int get(int key) {
if(map.containsKey(key)) {
Node node = map.get(key);
remove(node);
insert(node);
return node.value;
}
return -1;
}
public void put(int key, int value) {
if(map.containsKey(key)) {
Node node = map.get(key);
node.value = value;
remove(node);
insert(node);
}
else {
Node node = new Node(key, value);
if(map.size() >= n) {
Node temp = right.left;
remove(temp);
map.remove(temp.key);
}
insert(node);
}
}
}
94. 二叉树的中序遍历
94. 二叉树的中序遍历
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> ans = new ArrayList<>();
dfs(root,ans);
return ans;
}
public void dfs(TreeNode root, List<Integer> ans){
if(root == null) {
return;
}
dfs(root.left, ans);
ans.add(root.val);
dfs(root.right, ans);
}
}
104. 二叉树的最大深度
104. 二叉树的最大深度
class Solution {
int ans = 0;
public int maxDepth(TreeNode root) {
dfs(root, 1);
return ans;
}
public void dfs(TreeNode root, int k) {
if(root == null) {
return;
}
if(root.left == null && root.right ==null) {
ans = Math.max(ans, k);
}
if(root.left != null) dfs(root.left, k + 1);
if(root.right != null) dfs(root.right, k + 1);
}
}
226. 翻转二叉树
226. 翻转二叉树
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root == null) return root;
invertTree(root.left);
invertTree(root.right);
TreeNode left = root.left;
TreeNode right = root.right;
root.left = right;
root.right = left;
return root;
}
}
101. 对称二叉树
101. 对称二叉树
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root == null) return true;
return isSymmetric(root.left, root.right);
}
public boolean isSymmetric(TreeNode left, TreeNode right) {
if(left == null && right == null) return true;
if(left == null || right == null || left.val != right.val) return false;
return isSymmetric(left.left, right.right) && isSymmetric(left.right, right.left);
}
}
543. 二叉树的直径
543. 二叉树的直径
class Solution {
int ans = 0;
public int diameterOfBinaryTree(TreeNode root) {
if(root == null) return 0;
dfs(root);
return ans - 1;
}
public int dfs(TreeNode root) {
if(root == null) {
return 0;
}
int l = dfs(root.left);
int r = dfs(root.right);
ans = Math.max(ans, l + r + 1);
return Math.max(l,r) + 1;
}
}
102. 二叉树的层序遍历
102. 二叉树的层序遍历
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> ans = new ArrayList<>();
if(root == null) {
return ans;
}
Deque<TreeNode> dq = new ArrayDeque<>();
dq.offerLast(root);
while(!dq.isEmpty()) {
int size = dq.size();
List<Integer> temp = new ArrayList<>();
ans.add(temp);
for(int i = 0; i < size; i ++) {
TreeNode node = dq.pollFirst();
temp.add(node.val);
if(node.left != null) dq.offerLast(node.left);
if(node.right != null) dq.offerLast(node.right);
}
}
return ans;
}
}
108. 将有序数组转换为二叉搜索树
108. 将有序数组转换为二叉搜索树
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
int n = nums.length;
if(n == 0) { return null;}
return build(nums, 0, n - 1);
}
public TreeNode build(int[] nums, int l, int r) {
if(l > r) {
return null;
}
int mid = (l + r) >> 1;
TreeNode root = new TreeNode(nums[mid]);
root.left = build(nums, l, mid - 1);
root.right = build(nums, mid + 1, r);
return root;
}
}
98. 验证二叉搜索树
98. 验证二叉搜索树
class Solution {
Integer pre = null;
boolean res = true;
public boolean isValidBST(TreeNode root) {
if(root == null) return true;
dfs(root);
return res;
}
public void dfs(TreeNode root) {
if(root == null) return;
dfs(root.left);
if(pre != null && pre >= root.val) {
res = false;
return;
}
pre = root.val;
dfs(root.right);
}
}
230. 二叉搜索树中第 K 小的元素
230. 二叉搜索树中第 K 小的元素
class Solution {
int ans = 0;
int cur = 0;
int k = 0;
public int kthSmallest(TreeNode root, int _k) {
if(root == null) return ans;
k = _k;
dfs(root);
return ans;
}
public void dfs(TreeNode root) {
if(root == null) {
return;
}
dfs(root.left);
cur ++;
if(cur == k) ans = root.val;
if(cur > k) return;
dfs(root.right);
}
}
199. 二叉树的右视图
199. 二叉树的右视图
class Solution {
public List<Integer> rightSideView(TreeNode root) {
List<Integer> ans = new ArrayList<>();
if(root == null) return ans;
Deque<TreeNode> dq = new ArrayDeque<>();
dq.add(root);
while(!dq.isEmpty()) {
int size = dq.size();
for(int i = 0; i < size; i ++) {
TreeNode node = dq.pollFirst();
if(i == size - 1) {
ans.add(node.val);
}
if(node.left != null) dq.offerLast(node.left);
if(node.right != null) dq.offerLast(node.right);
}
}
return ans;
}
}
114. 二叉树展开为链表
114. 二叉树展开为链表
class Solution {
public void flatten(TreeNode root) {
while(root != null) {
TreeNode l = root.left;
if(l != null) {
while(l.right != null) {
l = l.right;
}
l.right = root.right;
root.right = root.left;
root.left = null;
}
root = root.right;
}
}
}
105. 从前序与中序遍历序列构造二叉树
105. 从前序与中序遍历序列构造二叉树
class Solution {
Map<Integer, Integer> map = new HashMap<>();
public TreeNode buildTree(int[] preorder, int[] inorder) {
int n = preorder.length;
if(n == 0) return null;
for(int i = 0; i < n; i ++) {
map.put(inorder[i], i);
}
return buildTree(preorder, inorder, 0, n - 1, 0, n - 1);
}
public TreeNode buildTree(int[] preorder, int[] inorder, int pl, int pr, int il, int ir) {
if(pl > pr) {
return null;
}
Integer rootIndex = map.get(preorder[pl]);
int len = rootIndex - il - 1;
TreeNode node = new TreeNode(preorder[pl]);
node.left = buildTree(preorder, inorder, pl + 1, pl + len + 1, il, rootIndex - 1);
node.right = buildTree(preorder, inorder, pl + len + 2, pr, rootIndex + 1, ir);
return node;
}
}
437. 路径总和 III
437. 路径总和 III
class Solution {
Map<Long, Integer> prefix = new HashMap<>();
int targetSum;
public int pathSum(TreeNode root, int _targetSum) {
if(root == null) return 0;
prefix.put(0L,1);
targetSum = _targetSum;
return dfs(root, 0);
}
public int dfs(TreeNode root, int curr) {
if(targetSum == null) {
return 0;
}
int ret = 0;
curr += root.val;
ret += prefix.getOrDefault(curr - targetSum, 0);
prefix.put(curr, prefix.getOrDefault(curr, 0) + 1);
ret += dfs(root.left, curr);
ret += dfs(root.right, curr);
prefix.put(curr, prefix.getOrDefault(curr, 0) -1);
return ret;
}
}
236. 二叉树的最近公共祖先
236. 二叉树的最近公共祖先
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null || p == root || q == root) {
return root;
}
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
return left == null ? right : right == null ? left : root;
}
}
124. 二叉树中的最大路径和
124. 二叉树中的最大路径和
class Solution {
Integer ans = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
if(root == null) return 0;
dfs(root);
return ans;
}
public int dfs(TreeNode root){
if(root == null) {
return 0;
}
int left = Math.max(0,dfs(root.left));
int right = Math.max(0,dfs(root.right));
ans = Math.max(ans, root.val + left + right);
return root.val + Math.max(left, right);
}
}
200. 岛屿数量
200. 岛屿数量
class Solution {
char[][] grid;
int[] dx = new int[]{1, 0, -1, 0};
int[] dy = new int[]{0, 1, 0, -1};
int n,m;
public int numIslands(char[][] _grid) {
grid = _grid;
int ans = 0;
n = grid.length;
m = grid[0].length;
for(int i = 0; i < n; i ++) {
for(int j = 0; j < m; j ++) {
if(grid[i][j] == '1') {
ans++;
dfs(i,j);
}
}
}
return ans;
}
public void dfs(int x, int y) {
grid[x][y] = '0';
for(int i = 0; i < 4; i ++) {
int nx = dx[i] + x;
int ny = dy[i] + y;
if(nx >=0 && nx < n && ny >= 0 && ny < m && grid[nx][ny] == '1') {
dfs(nx, ny);
}
}
}
}
994. 腐烂的橘子
994. 腐烂的橘子
class Solution {
int[] dx = new int[]{0,1,0,-1};
int[] dy = new int[]{1,0,-1,0};
public int orangesRotting(int[][] grid) {
int n = grid.length;
int m = grid[0].length;
Deque<Integer> dq = new ArrayDeque<>();
Map<Integer,Integer> map = new HashMap<>();
int ans = 0;
for(int i = 0; i < n; i ++) {
for(int j = 0; j < m; j ++) {
if(grid[i][j] == 2) {
int node = i * m + j;
dq.offerLast(node);
map.put(node, 0);
}
}
}
while(!dq.isEmpty()) {
int size = dq.size();
for(int k = 0; k < size; k ++) {
Integer node = dq.pollFirst();
int x = node / m;
int y = node % m;
for(int i = 0; i < 4; i ++) {
int nx = dx[i] + x;
int ny = dy[i] + y;
if(nx >= 0 && nx < n && ny >= 0 && ny < m && grid[nx][ny] == 1) {
grid[nx][ny] = 2;
int node2 = nx * m + ny;
dq.offerLast(node2);
int val = map.get(node) + 1;
map.put(node2, val);
ans = Math.max(ans, val);
}
}
}
}
for(int i = 0; i < n; i ++) {
for(int j = 0; j < m; j ++) {
if(grid[i][j] == 1) {
return -1;
}
}
}
return ans;
}
}
207. 课程表
207. 课程表
class Solution {
public boolean canFinish(int numCourses, int[][] prerequisites) {
Deque<Integer> dq = new ArrayDeque<>();
int[] inNum = new int[numCourses];
int[][] edge = new int[numCourses][numCourses];
for(int i = 0; i < prerequisites.length; i ++) {
inNum[prerequisites[i][1]] ++;
edge[prerequisites[i][0]][prerequisites[i][1]] = 1;
}
int cnt = 0;
for(int i = 0; i < numCourses; i++) {
if(inNum[i] == 0) {
dq.offerLast(i);
}
}
while(!dq.isEmpty()) {
cnt ++;
int k = dq.pollFirst();
for(int i = 0; i < numCourses; i ++) {
if(edge[k][i] == 1) {
inNum[i] --;
if(inNum[i] == 0) {
dq.offerLast(i);
}
}
}
}
return cnt == numCourses;
}
}
208. 实现 Trie (前缀树)
208. 实现 Trie (前缀树)
class Trie {
public Trie[] children;
public boolean flag;
public Trie() {
children = new Trie[26];
flag = false;
}
public void insert(String word) {
Trie trie = this;
int n = word.length();
for (int i = 0; i < n; i++) {
int index = word.charAt(i) - 'a';
if (trie.children[index] == null) {
trie.children[index] = new Trie();
}
trie = trie.children[index];
}
trie.flag = true;
}
public Trie searchPrifix(String word) {
Trie trie = this;
for (int i = 0; i < word.length(); i++) {
int index = word.charAt(i) - 'a';
if (trie.children[index] == null) {
return null;
}
trie = trie.children[index];
}
return trie;
}
public boolean search(String word) {
Trie trie = searchPrifix(word);
return trie != null && trie.flag;
}
public boolean startsWith(String prefix) {
return searchPrifix(prefix) != null;
}
}
46. 全排列
46. 全排列
class Solution {
List<List<Integer>> ans = new ArrayList<>();
boolean[] f;
int n;
public List<List<Integer>> permute(int[] nums) {
n = nums.length;
f = new boolean[n];
List<Integer> path = new ArrayList<>();
dfs(nums, 0, path);
return ans;
}
public void dfs(int[] nums, int k, List<Integer> path) {
if(k == n) {
ans.add(new ArrayList<>(path));
return;
}
for(int i = 0; i < n; i ++) {
if(!f[i]) {
f[i] = true;
path.add(nums[i]);
dfs(nums, k + 1, path);
path.remove(path.size() - 1);
f[i] = false;
}
}
}
}
78. 子集
78. 子集
class Solution {
List<List<Integer>> ans = new ArrayList<>();
public List<List<Integer>> subsets(int[] nums) {
List<Integer> path = new ArrayList<>();
dfs(nums, 0, path);
return ans;
}
public void dfs(int[] nums, int cnt, List<Integer> path) {
if (cnt == nums.length) {
ans.add(new ArrayList<>(path));
return;
}
dfs(nums, cnt + 1, path);
path.add(nums[cnt]);
dfs(nums, cnt + 1, path);
path.remove(path.size() - 1);
}
}
17. 电话号码的字母组合
17. 电话号码的字母组合
class Solution {
char[][] ch = 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' }
};
List<String> ans = new ArrayList<>();
public List<String> letterCombinations(String digits) {
if(digits == null || digits.equals("")) {
return ans;
}
int n = digits.length();
StringBuilder sb = new StringBuilder();
dfs(0, digits, sb);
return ans;
}
public void dfs(int k, String s, StringBuilder sb) {
if(k == s.length()) {
ans.add(sb.toString());
return;
}
int index = s.charAt(k) - '2';
for(int i = 0; i < ch[index].length;i++) {
sb.append(ch[index][i]);
dfs(k + 1, s, sb);
sb.delete(sb.length() - 1, sb.length());
}
}
}
39. 组合总和
39. 组合总和
class Solution {
List<List<Integer>> ans = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> combinationSum(int[] candidates, int target) {
dfs(candidates, target, 0);
return ans;
}
public void dfs(int[] nums, int target, int cur) {
if(target == 0) {
ans.add(new ArrayList<>(path));
return;
}
if(cur >= nums.length) {
return;
}
for(int i = 0; i * nums[cur] <= target; i ++) {
dfs(nums, target - i * nums[cur], cur + 1);
path.add(nums[cur]);
}
for(int i = 0; i * nums[cur] <= target; i ++) {
path.remove(path.size() - 1);
}
}
}
22. 括号生成
22. 括号生成
class Solution {
List<String> ans = new ArrayList<>();
StringBuilder sb = new StringBuilder();
public List<String> generateParenthesis(int n) {
if(n == 0) return ans;
dfs(0,0,n);
return ans;
}
public void dfs(int l, int r, int n) {
if(l == r && l == n) {
ans.add(sb.toString());
return;
}
if(l > n || r > n || r > l) {
return;
}
if(l == r) {
sb.append('(');
dfs(l + 1, r, n);
sb.delete(sb.length() - 1, sb.length());
} else if(l > r) {
sb.append(')');
dfs(l, r + 1, n);
sb.delete(sb.length() - 1, sb.length());
sb.append('(');
dfs(l + 1, r, n);
sb.delete(sb.length() - 1, sb.length());
}
}
}
79. 单词搜索
79. 单词搜索
class Solution {
boolean ans = false;
int[] dx = new int[]{0,1,0,-1};
int[] dy = new int[]{1,0,-1,0};
int n, m;
boolean[][] f;
public boolean exist(char[][] board, String word) {
n = board.length;
m = board[0].length;
f = new boolean[n][m];
for(int i = 0; i < n; i ++) {
for(int j = 0; j < m; j ++) {
if(board[i][j] == word.charAt(0)) {
f[i][j] = true;
dfs(board, word, 1, i, j);
f[i][j] = false;
}
}
}
return ans;
}
public void dfs(char[][] board, String word, int k,int x, int y) {
if(k == word.length()) {
ans = true;
return;
}
for(int i = 0; i < 4; i ++) {
int nx = dx[i] + x;
int ny = dy[i] + y;
if(nx>=0 && nx < n && ny >= 0 && ny < m && board[nx][ny] == word.charAt(k) && !f[nx][ny]) {
f[nx][ny] = true;
dfs(board, word, k + 1, nx, ny);
f[nx][ny] = false;
}
}
}
}
131. 分割回文串
131. 分割回文串
class Solution {
Deque<String> path = new ArrayDeque<>();
List<List<String>> ans = new ArrayList<>();
public List<List<String>> partition(String s) {
if (s == null || s.equals(""))
return ans;
int len = s.length();
boolean[][] dp = new boolean[len][len];
for (int i = 0; i < len; i++) {
for (int j = 0; j <= i; j++) {
if (s.charAt(i) == s.charAt(j) && ((i - j <= 2 || dp[j+1][i-1]))) {
dp[j][i] = true;
}
}
}
dfs(s, dp, 0);
return ans;
}
public void dfs(String s, boolean[][] dp, int k) {
if (k == s.length()) {
ans.add(new ArrayList(path));
return;
}
for (int i = k; i < s.length(); i++) {
if (dp[k][i]) {
path.offerLast(s.substring(k, i + 1));
dfs(s, dp, i + 1);
path.pollLast();
}
}
}
}
51. N 皇后
51. N 皇后
class Solution {
int n;
boolean[] row;
boolean[] col;
boolean[] dg;
boolean[] udg;
List<List<String>> ans = new ArrayList<>();
char[][] matrix;
public List<List<String>> solveNQueens(int _n) {
n = _n;
col = new boolean[n];
dg = new boolean[2 * n];
udg = new boolean[2 * n];
matrix = new char[n][n];
for (int i = 0; i < n; i++) {
Arrays.fill(matrix[i], '.');
}
dfs(0);
return ans;
}
public void dfs(int k) {
if (k == n) {
List<String> res = new ArrayList<>();
for (int i = 0; i < n; i++) {
res.add(new String(matrix[i]));
}
ans.add(res);
return;
}
for (int i = 0; i < n; i++) {
if (!col[i] && !dg[k - i + n] && !udg[i + k]) {
col[i] = dg[k - i + n] = udg[i + k] = true;
matrix[k][i] = 'Q';
dfs(k + 1);
matrix[k][i] = '.';
col[i] = dg[k - i + n] = udg[i + k] = false;
}
}
}
}
35. 搜索插入位置
35. 搜索插入位置
class Solution {
public int searchInsert(int[] nums, int target) {
int l = 0, r = nums.length - 1;
while(l < r) {
int mid = (l + r) >> 1;
if(nums[mid] > target) {
r = mid;
} else if(nums[mid] == target) {
r = mid;
} else {
l = mid + 1;
}
}
if(l == nums.length - 1 && target > nums[l]) {
return l + 1;
}
return l;
}
}
74. 搜索二维矩阵
74. 搜索二维矩阵
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int n = matrix.length;
int m = matrix[0].length;
for(int i = 0; i < n; i ++) {
if(matrix[i][m - 1] >= target) {
for(int j = 0; j < m; j ++) {
if(matrix[i][j] == target) {
return true;
}
}
}
}
return false;
}
}
34. 在排序数组中查找元素的第一个和最后一个位置
34. 在排序数组中查找元素的第一个和最后一个位置
class Solution {
public int[] searchRange(int[] nums, int target) {
if(nums.length == 0) return new int[]{-1,-1};
int l = 0, r= nums.length -1 ;
while(l < r) {
int mid = (l + r) >> 1;
if(nums[mid] >= target) r = mid;
else l = mid + 1;
}
if(nums[l] != target) {
return new int[]{-1,-1};
}
int[] ans = new int[2];
ans[0] = l;
l = 0; r = nums.length - 1;
while(l < r) {
int mid = (l + r + 1) >> 1;
if(nums[mid] <= target) l = mid;
else r = mid - 1;
}
ans[1] = r;
return ans;
}
}
33. 搜索旋转排序数组
33. 搜索旋转排序数组
class Solution {
public int search(int[] nums, int target) {
int n = nums.length;
int l = 0, r = n - 1;
while(l < r) {
int mid = (l + r + 1) >> 1;
if(nums[mid] >= nums[0]) l = mid;
else r = mid - 1;
}
if(target >= nums[0]) {
l = 0;
} else {
l = l + 1;
r = n - 1;
}
while (l < r) {
int mid = (l + r) >> 1;
if (nums[mid] >= target) r = mid;
else l = mid + 1;
}
return nums[r] == target ? r : -1;
}
}
153. 寻找旋转排序数组中的最小值
153. 寻找旋转排序数组中的最小值
class Solution {
public int findMin(int[] nums) {
int l = 0, r = nums.length - 1;
while(l < r) {
int mid = (l + r + 1) >> 1;
if(nums[mid] >= nums[0]) l = mid;
else r = mid - 1;
}
if(r == nums.length - 1) {
return nums[0];
}
if(nums[r] > nums[r + 1]) {
return nums[r + 1];
}
return nums[0];
}
}
4. 寻找两个正序数组的中位数
4. 寻找两个正序数组的中位数
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
if (nums1.length > nums2.length){
int[] temp = nums1;
nums1 = nums2;
nums2 = temp;
}
int n = nums1.length;
int m = nums2.length;
int totalLeft = (m + n + 1) >> 1;
int left = 0;
int right = n;
while ( left < right){
int i = left + ((right - left + 1) >> 1);
int j = totalLeft - i;
if (nums1[i-1] >nums2[j]) {
right = i - 1;
}else{
left = i;
}
}
int i = left;
int j = totalLeft - i;
int nums1LeftMax = i == 0 ? Integer.MIN_VALUE : nums1[i-1];
int nums1RightMin = i == n ? Integer.MAX_VALUE : nums1[i];
int nums2LeftMax = j == 0 ? Integer.MIN_VALUE : nums2[j-1];
int nums2RightMin = j == m ? Integer.MAX_VALUE : nums2[j];
if ( ((m+n) &1) == 1){
return Math.max(nums1LeftMax,nums2LeftMax);
}else {
return (double)((Math.max(nums1LeftMax,nums2LeftMax) + Math.min(nums1RightMin,nums2RightMin) )) /2 ;
}
}
}
20. 有效的括号
20. 有效的括号
class Solution {
public boolean isValid(String s) {
if (s == null || s.equals(""))
return true;
Deque<Character> dq = new ArrayDeque<>();
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(' || s.charAt(i) == '{' || s.charAt(i) == '[') {
dq.offerLast(s.charAt(i));
} else if (s.charAt(i) == ')') {
if (!dq.isEmpty() && dq.peekLast() == '(') {
dq.pollLast();
} else {
return false;
}
} else if (s.charAt(i) == '}') {
if (!dq.isEmpty() && dq.peekLast() == '{') {
dq.pollLast();
} else {
return false;
}
} else if (s.charAt(i) == ']') {
if (!dq.isEmpty() && dq.peekLast() == '[') {
dq.pollLast();
} else {
return false;
}
}
}
return dq.isEmpty();
}
}
155. 最小栈
155. 最小栈
class MinStack {
Deque<Integer> stack;
Deque<Integer> minStack;
public MinStack() {
stack = new ArrayDeque<>();
minStack = new ArrayDeque<>();
minStack.offerLast(Integer.MAX_VALUE);
}
public void push(int val) {
stack.offerLast(val);
minStack.offerLast(Math.min(minStack.peekLast(), val));
}
public void pop() {
stack.pollLast();
minStack.pollLast();
}
public int top() {
return stack.peekLast();
}
public int getMin() {
return minStack.peekLast();
}
}
394. 字符串解码
394. 字符串解码
class Solution {
public String decodeString(String s) {
Deque<String> str = new ArrayDeque<>();
Deque<Integer> num = new ArrayDeque<>();
String curStr = "";
int k = 0;
for (int i = 0; i < s.length();i++) {
char ch = s.charAt(i);
if(Character.isDigit(ch)) {
k = k * 10 + (ch - '0');
} else if(ch == '[') {
num.offerLast(k);
str.offerLast(curStr);
curStr = "";
k = 0;
} else if(ch ==']') {
StringBuilder temp = new StringBuilder(str.pollLast());
int cnt = num.pollLast();
for(int j = 0; j < cnt; j ++) {
temp.append(curStr);
}
curStr = temp.toString();
} else {
curStr += ch;
}
}
return curStr;
}
}
739. 每日温度
739. 每日温度
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
Deque<Integer> dq = new ArrayDeque<>();
int len = temperatures.length;
int[] r = new int[len];
Arrays.fill(r, len);
for(int i = 0; i < len; i ++) {
while(!dq.isEmpty() && temperatures[dq.peekLast()] < temperatures[i] ) {
int index = dq.pollLast();
r[index] = i;
}
dq.offerLast(i);
}
int[] ans = new int[len];
for(int i = 0; i < len; i ++) {
if(r[i] != len) {
ans[i] = r[i] - i;
} else {
ans[i] = 0;
}
}
return ans;
}
}
84. 柱状图中最大的矩形
84. 柱状图中最大的矩形
class Solution {
public int largestRectangleArea(int[] heights) {
Deque<Integer> dq = new ArrayDeque<>();
int len = heights.length;
int[] r = new int[len];
int[] l = new int[len];
Arrays.fill(r, len);
for(int i = 0; i < len; i ++) {
while(!dq.isEmpty() && heights[i] <= heights[dq.peekLast()]) {
int index = dq.pollLast();
r[index] = i;
}
l[i] = dq.isEmpty() ? -1 : dq.peekLast();
dq.offerLast(i);
}
int res = 0;
for (int i = 0; i < len; i++) {
res = Math.max(res, heights[i] * (r[i] - l[i] - 1));
}
return res;
}
}
215. 数组中的第K个最大元素
215. 数组中的第K个最大元素
class Solution {
public int largestRectangleArea(int[] heights) {
Deque<Integer> dq = new ArrayDeque<>();
int len = heights.length;
int[] r = new int[len];
int[] l = new int[len];
Arrays.fill(r, len);
for(int i = 0; i < len; i ++) {
while(!dq.isEmpty() && heights[i] <= heights[dq.peekLast()]) {
int index = dq.pollLast();
r[index] = i;
}
l[i] = dq.isEmpty() ? -1 : dq.peekLast();
dq.offerLast(i);
}
int res = 0;
for (int i = 0; i < len; i++) {
res = Math.max(res, heights[i] * (r[i] - l[i] - 1));
}
return res;
}
}
347. 前 K 个高频元素
347. 前 K 个高频元素
class Solution {
public int[] topKFrequent(int[] nums, int k) {
Map<Integer,Integer> map = new HashMap<>();
int len = nums.length;
for(int i = 0; i < len; i ++) {
map.put(nums[i], map.getOrDefault(nums[i], 0) + 1);
}
List<Integer>[] list = new List[len + 1];
map.forEach((key,v)-> {
if(list[v] == null) {
list[v] = new ArrayList<>();
}
list[v].add(key);
});
int cnt = 0;
int[] ans = new int[k];
for(int i = len; i >= 0; i --) {
if(list[i] != null) {
for(int j = 0; j <list[i].size() && cnt < k; j ++) {
ans[cnt++] = list[i].get(j);
}
}
}
return ans;
}
}
295. 数据流的中位数
295. 数据流的中位数
class MedianFinder {
PriorityQueue<Integer> queMin;
PriorityQueue<Integer> queMax;
public MedianFinder() {
queMin = new PriorityQueue<Integer>((a,b)-> (b-a));
queMax = new PriorityQueue<Integer>((a,b)-> (a-b));
}
public void addNum(int num) {
if(queMin.isEmpty() || num <= queMin.peek()) {
queMin.offer(num);
if(queMax.size() + 1 < queMin.size()) {
queMax.offer(queMin.poll());
}
} else {
queMax.offer(num);
if(queMax.size() > queMin.size()) {
queMin.offer(queMax.poll());
}
}
}
public double findMedian() {
if(queMin.size() > queMax.size()) {
return queMin.peek();
}
return (queMin.peek() + queMax.peek()) / 2.0;
}
}
121. 买卖股票的最佳时机
121. 买卖股票的最佳时机
class Solution {
public int maxProfit(int[] prices) {
int min = Integer.MAX_VALUE;
int ans = 0;
for(int i = 0; i < prices.length; i ++) {
if(prices[i] < min) {
min = prices[i];
} else {
ans = Math.max(ans, prices[i] -min );
}
}
return ans;
}
}
55. 跳跃游戏
55. 跳跃游戏
class Solution {
public boolean canJump(int[] nums) {
int n = nums.length;
int r = 0;
for(int i = 0; i < n; i ++) {
if(i<=r) {
r = Math.max(r, i + nums[i]);
if(r >= n - 1) {
return true;
}
}
}
return false;
}
}
45. 跳跃游戏 II
45. 跳跃游戏 II
class Solution {
public int jump(int[] nums) {
int n = nums.length;
int[] dp = new int[n];
for(int i = 1, j = 0; i < n; i ++) {
while(j + nums[j] < i) j ++;
dp[i] = dp[j] + 1;
}
return dp[n - 1];
}
}
763. 划分字母区间
763. 划分字母区间
class Solution {
public List<Integer> partitionLabels(String s) {
int[] last = new int[26];
int len = s.length();
for(int i = 0; i < len; i ++) {
last[s.charAt(i) - 'a'] = i;
}
List<Integer> partion = new ArrayList<>();
int l = 0, r = 0;
for(int i = 0; i < len; i ++) {
r = Math.max(r, last[s.charAt(i) - 'a']);
if(i == r) {
partion.add(r - l + 1);
l = r + 1;
}
}
return partion;
}
}
70. 爬楼梯
70. 爬楼梯
class Solution {
public int climbStairs(int n) {
int[] dp = new int[n + 1];
if(n<= 2) {
return n;
}
dp[1] = 1;
dp[2] = 2;
for(int i = 3; i <= n; i ++) {
dp[i] = dp[i-1] + dp[i-2];
}
return dp[n];
}
}
118. 杨辉三角
118. 杨辉三角
class Solution {
public List<List<Integer>> generate(int numRows) {
List<List<Integer>> ans = new ArrayList<>();
List<Integer> first = new ArrayList<>();
first.add(1);
ans.add(first);
if(numRows == 1) {
return ans;
}
List<Integer> second = new ArrayList<>();
ans.add(second);
second.add(1);
second.add(1);
if(numRows == 2) {
return ans;
}
for(int i = 2; i < numRows; i ++) {
List<Integer> temp = new ArrayList<>();
ans.add(temp);
temp.add(1);
List<Integer> pre = ans.get(i -1 );
for(int j = 1; j < i; j ++) {
temp.add(pre.get(j-1) + pre.get(j));
}
temp.add(1);
}
return ans;
}
}
198. 打家劫舍
198. 打家劫舍
class Solution {
public int rob(int[] nums) {
int len = nums.length;
int[] dp = new int[len];
for(int i = 0; i < len; i ++) {
dp[i] = nums[i];
if(i == 1) {
dp[i] = Math.max(nums[i-1], nums[i]);
}
if(i >= 2) {
dp[i] = Math.max(dp[i-2] + nums[i], dp[i-1] );
}
}
return dp[len-1];
}
}
279. 完全平方数
279. 完全平方数
class Solution {
public int numSquares(int n) {
int[] f = new int[n + 1];
for(int i = 1; i <= n; i ++) {
int min = Integer.MAX_VALUE;
for(int j = 1; j * j <= i; j ++) {
min = Math.min(min, f[i - j*j]);
}
f[i] = min + 1;
}
return f[n];
}
}
322. 零钱兑换
322. 零钱兑换
class Solution {
public int coinChange(int[] coins, int amount) {
int n = coins.length;
int[] f = new int[amount + 1];
int max = amount + 1;
Arrays.fill(f, max);
f[0] = 0;
for(int i = 1; i <= amount; i++ ) {
for(int j = 0; j < coins.length; j ++) {
if(coins[j] <= i) {
f[i] = Math.min(f[i], f[i - coins[j]] + 1);
}
}
}
return f[amount] > amount ? -1 : f[amount];
}
}
139. 单词拆分
139. 单词拆分
class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
Set<Long> set = new HashSet<>();
boolean[] f= new boolean[s.length() + 1];
int P = 131;
for(int i = 0; i < wordDict.size(); i ++) {
long a = 0L;
for(int j = 0; j < wordDict.get(i).length(); j ++) {
a = a * P + wordDict.get(i).charAt(j) ;
}
set.add(a);
}
int n = s.length();
boolean[] dp = new boolean[n + 1];
dp[n] = true;
for(int i = n - 1; i >= 0; i --) {
long a = 0L;
for(int j = i; j < n; j ++) {
a = a * P + s.charAt(j);
if(set.contains(a) && dp[j + 1]) {
dp[i] = true;
break;
}
}
}
return dp[0];
}
}
300. 最长递增子序列
300. 最长递增子序列
class Solution {
public int lengthOfLIS(int[] nums) {
int len = 1, n = nums.length;
if (n == 0) {
return 0;
}
int[] d = new int[n + 1];
d[len] = nums[0];
for(int i = 1; i < n; i ++) {
if(nums[i] > d[len]) {
d[++len] = nums[i];
} else {
int l = 1, r = len, pos = 0;
while(l <= r) {
int mid = (l + r) >> 1;
if(d[mid] < nums[i]) {
pos = mid;
l = mid + 1;
} else {
r = mid - 1;
}
}
d[pos + 1] = nums[i];
}
}
return len;
}
}
152. 乘积最大子数组
152. 乘积最大子数组
class Solution {
public int maxProduct(int[] nums) {
long max = nums[0], min = nums[0];
int ans = nums[0];
int length = nums.length;
for (int i = 1; i < length; i++) {
long mx = max, mn = min;
max = Math.max(mx * nums[i], Math.max(nums[i], mn * nums[i]));
min = Math.min(mn * nums[i], Math.min(nums[i], mx * nums[i]));
if (min < -1 << 31) {
min = nums[i];
}
ans = Math.max((int) max, ans);
}
return ans;
}
}
416. 分割等和子集
416. 分割等和子集
class Solution {
public boolean canPartition(int[] nums) {
int n = nums.length;
if(n < 2) {
return false;
}
int sum = 0, maxNum = 0;
for(int num : nums) {
sum += num;
maxNum = Math.max(maxNum, num);
}
if(sum % 2 != 0) {
return false;
}
int target = sum / 2;
if(maxNum > target) {
return false;
}
boolean[][] dp = new boolean[n][target + 1];
for(int i = 0; i < n; i ++) {
dp[i][0] = true;
}
dp[0][nums[0]] = true;
for(int i = 1; i < n; i ++) {
int num = nums[i];
for(int j = 1; j <= target; j ++) {
if(j >= num) {
dp[i][j] = dp[i-1][j] | dp[i-1][j - num];
} else {
dp[i][j] = dp[i-1][j];
}
}
}
return dp[n-1][target];
}
}
32. 最长有效括号
32. 最长有效括号
class Solution {
public int longestValidParentheses(String s) {
int len = s.length();
Deque<Integer> dq = new ArrayDeque<>();
int ans = 0;
for (int i = 0, l = -1; i < len; i++) {
char ch = s.charAt(i);
if (ch == '(') {
dq.offerLast(i);
} else {
if (!dq.isEmpty()) {
dq.pollLast();
if (!dq.isEmpty()) {
ans = Math.max(ans, i - dq.peekLast());
} else {
ans = Math.max(ans, i - l);
}
} else {
l = i;
}
}
}
return ans;
}
}
62. 不同路径
62. 不同路径
class Solution {
public int uniquePaths(int m, int n) {
int[][] dp = new int[m][n];
for(int i = 0; i < m; i ++) {
for(int j = 0; j < n; j ++) {
if(i == 0 && j == 0) {
dp[i][j] = 1;
} else if(i == 0) {
dp[i][j] = dp[i][j-1];
} else if(j== 0) {
dp[i][j] = dp[i-1][j];
} else {
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
}
return dp[m-1][n-1];
}
}
64. 最小路径和
64. 最小路径和
class Solution {
public int minPathSum(int[][] grid) {
int n = grid.length;
int m = grid[0].length;
int[][] dp = new int[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (i == 0 && j == 0) {
dp[i][j] = grid[i][j];
} else if (i == 0) {
dp[i][j] = grid[i][j] + dp[i][j - 1];
} else if (j == 0) {
dp[i][j] = grid[i][j] + dp[i-1][j];
} else {
dp[i][j] = grid[i][j] + Math.min(dp[i - 1][j], dp[i][j-1]);
}
}
}
return dp[n - 1][m - 1];
}
}
5. 最长回文子串
5. 最长回文子串
class Solution {
public String longestPalindrome(String s) {
int len = s.length();
boolean[][] dp = new boolean[len][len];
int maxLen = 0;
int l = 0, r = 0;
for (int i = 0; i < len; i++) {
for (int j = 0; j <= i; j++) {
if (s.charAt(i) == s.charAt(j) && ((i - j <= 2 || dp[j+1][i-1]))) {
dp[j][i] = true;
int length = i - j + 1;
if(length > maxLen) {
l = j; r = i;
maxLen = length;
}
}
}
}
return s.substring(l, r + 1);
}
}
1143. 最长公共子序列
1143. 最长公共子序列
class Solution {
public int longestCommonSubsequence(String text1, String text2) {
int n = text1.length(), m = text2.length();
int[][] dp = new int[n + 1][m + 1];
for(int i = 1; i <= n; i ++) {
for(int j = 1; j <= m; j ++) {
if(text1.charAt(i-1) == text2.charAt(j-1)) {
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[n][m];
}
}
72. 编辑距离
72. 编辑距离
class Solution {
public int minDistance(String word1, String word2) {
int n = word1.length();
int m = word2.length();
word1 = " " + word1;
word2 = " " + word2;
int[][] dp = new int[n + 1][m + 1];
for(int i = 1; i <= n; i ++) {
dp[i][0] = i;
}
for(int j = 1; j <= m; j ++) {
dp[0][j] = j;
}
for(int i = 1; i <= n; i ++) {
for(int j = 1; j <= m; j ++) {
dp[i][j] = Math.min(dp[i-1][j], dp[i][j-1]) + 1;
dp[i][j] = Math.min(dp[i][j], dp[i-1][j-1] + (word1.charAt(i) == word2.charAt(j) ? 0 : 1));
}
}
return dp[n][m];
}
}
136. 只出现一次的数字
136. 只出现一次的数字
class Solution {
public int singleNumber(int[] nums) {
int ans = 0;
for(int i = 0; i < nums.length; i ++) {
ans ^= nums[i];
}
return ans;
}
}
169. 多数元素
169. 多数元素
class Solution {
public int majorityElement(int[] nums) {
int count = 0;
int ans = 0;
for(int i = 0; i < nums.length; i ++) {
if(count == 0) {
ans = nums[i];
}
count += ans == nums[i] ? 1 : -1;
}
return ans;
}
}
75. 颜色分类
75. 颜色分类
class Solution {
public void sortColors(int[] nums) {
int zero = 0;
int two = nums.length - 1;
for(int i = 0; i < nums.length; i ++) {
while (i <= two && nums[i] == 2) {
swap(nums, i, two);
two--;
}
if(nums[i] == 0) {
swap(nums, i, zero);
zero ++;
}
}
}
public void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
31. 下一个排列
31. 下一个排列
class Solution {
public void nextPermutation(int[] nums) {
int k = nums.length - 1;
while (k > 0 && nums[k - 1] >= nums[k]) k--;
if (k <= 0) {
reverse(nums, 0, nums.length - 1);
} else {
int t = k;
while (t < nums.length && nums[t] > nums[k - 1]) t++;
swap(nums, t - 1, k - 1);
reverse(nums, k, nums.length - 1);
}
}
public void reverse(int[] nums, int l, int r) {
while (l < r) {
swap(nums, l, r);
l++;
r--;
}
}
public void swap(int[] nums, int l, int r) {
int temp = nums[l];
nums[l] = nums[r];
nums[r] = temp;
}
}
287. 寻找重复数
287. 寻找重复数
class Solution {
public int findDuplicate(int[] nums) {
int slow = 0, fast = 0;
do{
slow = nums[slow];
fast = nums[nums[fast]];
}while(slow != fast);
slow = 0;
while(slow != fast) {
slow = nums[slow];
fast = nums[fast];
}
return fast;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧