1. leetcode206 反转链表
1.1 解题思路1:迭代
1.2 代码实现1😊
// 时间复杂度:O(N)
// 空间复杂度:O(1)
class Solution {
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while (curr != null) {
ListNode next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
}
}
1.3 解题思路2:递归
1.4 代码实现2😊
// 时间复杂度:O(N)
// 空间复杂度:O(N)
class Solution {
public ListNode reverseList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode p = reverseList(head.next);
head.next.next = head;
head.next = null;
return p;
}
}
2. leetcode88合并两个有序数组
2.1 解题思路:逆向双指针
2.2 代码实现😊
// 时间复杂度:O(m + n)
// 空间复杂度:O(1)
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
int i = m - 1;
int j = n - 1;
int k = m + n - 1;
while (j >= 0) {
if (i >= 0 && nums1[i] >= nums2[j]) {
nums1[k--] = nums1[i--];
} else {
nums1[k--] = nums2[j--];
}
}
}
}
3. leetcode3 无重复字符的最长子串
3.1 解题思路:滑动窗口
3.2 代码实现😊
// 时间复杂度:O(N)
// 空间复杂度:O(∣Σ∣)
class Solution {
public int lengthOfLongestSubstring(String s) {
Map<Character, Integer> map = new HashMap<>();
int ans = 0;
for (int end = 0, start = 0; end < s.length(); end++) {
char temp = s.charAt(end);
if (map.containsKey(temp)) {
// 防止start左移
start = Math.max(start, map.get(temp) + 1);
}
ans = Math.max(ans, end - start + 1);
map.put(temp, end);
}
return ans;
}
}
4. 手撕快速排序
4.1 代码实现😊
// 时间复杂度:O(NlogN)
class Solution {
public void quickSort(int[] nums, int low, int high) {
if (low < high) {
int pivotPos = partition(nums, low, high);
quickSort(nums, low, pivotPos - 1);
quickSort(nums, pivotPos + 1, high);
}
}
private int partition(int[] nums, int low, int high) {
int pivot = nums[low];
while (low < high) {
while (low < high && nums[high] >= pivot)
--high;
nums[low] = nums[high];
while (low < high && nums[low] < pivot)
++low;
nums[high] = nums[low];
}
nums[low] = pivot;
return low;
}
}
5. leetcode21 合并两个有序链表
5.1 解题思路1:迭代
5.2 代码实现😊
class Solution {
// 时间复杂度:O(m + n)
// 空间复杂度:O(1)
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(-1);
ListNode point = dummy;
while (l1 != null && l2 != null) {
if (l1.val <= l2.val) {
point.next = l1;
l1 = l1.next;
} else {
point.next = l2;
l2 = l2.next;
}
point = point.next;
}
if (l1 != null)
point.next = l1;
if (l2 != null)
point.next = l2;
return dummy.next;
}
}
5.3 解题思路2:递归
5.4 代码实现😊
class Solution {
// 时间复杂度:O(m + n)
// 空间复杂度:O(m + n)
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null) {
return l2;
} else if (l2 == null) {
return l1;
} else if (l1.val <= l2.val) {
l1.next = mergeTwoLists(l1.next, l2);
return l1;
} else {
l2.next = mergeTwoLists(l1, l2.next);
return l2;
}
}
}
6. leetcode23 合并K个升序链表
6.1 解题思路1:顺序合并
6.2 代码实现
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0)
return null;
ListNode outputList = lists[0];
for (int i = 1; i < lists.length; i++) {
outputList = mergeTwoLists(outputList, lists[i]);
}
return outputList;
}
private ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null) {
return l2;
} else if (l2 == null) {
return l1;
} else if (l1.val <= l2.val) {
l1.next = mergeTwoLists(l1.next, l2);
return l1;
} else {
l2.next = mergeTwoLists(l1, l2.next);
return l2;
}
}
}
6.3 解题思路2:分治解法
6.4 代码实现
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0)
return null;
return merge(lists, 0, lists.length - 1);
}
private ListNode merge(ListNode[] listNodes, int left, int right) {
if (left == right)
return listNodes[left];
if (left > right)
return null;
int mid = left + (right - left) / 2;
ListNode mergedLeft = merge(listNodes, left, mid);
ListNode mergedRight = merge(listNodes, mid + 1, right);
return mergeTwoLists(mergedLeft, mergedRight);
}
private ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null) {
return l2;
} else if (l2 == null) {
return l1;
} else if (l1.val <= l2.val) {
l1.next = mergeTwoLists(l1.next, l2);
return l1;
} else {
l2.next = mergeTwoLists(l1, l2.next);
return l2;
}
}
}
6.5 解题思路3:优先队列
6.6 代码实现😊
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
PriorityQueue<ListNode> priorityQueue =
new PriorityQueue<>((o1, o2) -> o1.val - o2.val);
for (int i = 0; i < lists.length; i++) {
if (lists[i] == null)
continue;
priorityQueue.add(lists[i]);
}
ListNode dummy = new ListNode(-1);
ListNode curr = dummy;
while (!priorityQueue.isEmpty()) {
ListNode minNode = priorityQueue.remove();
curr.next = minNode;
curr = curr.next;
if (minNode.next != null) {
priorityQueue.add(minNode.next);
}
}
return dummy.next;
}
}
7. leetcode53 最大子序和
7.1 代码实现😊:动态规划
class Solution {
public int maxSubArray(int[] nums) {
// 1. 状态定义:dp[i] 表示以索引为 i 的元素结尾的最大子数组之和
int[] dp = new int[nums.length];
// 2. 状态初始化
dp[0] = nums[0];
int maxSum = nums[0];
// 3. 状态转移
for (int i = 1; i < nums.length; i++) {
dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]);
maxSum = Math.max(maxSum, dp[i]);
}
// 4. 返回状态值
return maxSum;
}
}
8. leetcode102 二叉树的层序遍历
8.1 代码实现1:😊迭代
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if (root == null)
return res;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size();
List<Integer> levelNodes = new ArrayList<>();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
levelNodes.add(node.val);
if (node.left != null)
queue.offer(node.left);
if (node.right != null)
queue.offer(node.right);
}
res.add(levelNodes);
}
return res;
}
}
8.2 代码实现2:😊递归
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if (root == null)
return res;
dfs(root, 0, res);
return res;
}
private void dfs(TreeNode node, int currLevel, List<List<Integer>> res) {
if (node == null)
return;
if (res.size() == currLevel) {
List<Integer> levelNodes = new ArrayList<>();
levelNodes.add(node.val);
res.add(levelNodes);
} else {
res.get(currLevel).add(node.val);
}
dfs(node.left, currLevel + 1, res);
dfs(node.right, currLevel + 1, res);
}
}
9. leetcode146 LRU缓存机制
9.1 代码实现😊
class LRUCache {
class DListNode {
int key;
int value;
DListNode prev;
DListNode next;
public DListNode() {
}
public DListNode(int key, int value) {
this.key = key;
this.value = value;
}
}
Map<Integer, DListNode> cache = new HashMap<>();
int capacity;
DListNode head;
DListNode tail;
public LRUCache(int capacity) {
this.capacity = capacity;
head = new DListNode();
tail = new DListNode();
head.next = tail;
tail.prev = head;
}
public int get(int key) {
DListNode node = cache.get(key);
if (node == null) {
return -1;
} else {
moveNodeToHead(node);
return node.value;
}
}
public void put(int key, int value) {
DListNode node = cache.get(key);
if (node == null) {
if (cache.size() == capacity) {
DListNode delNode = removeTailNode();
cache.remove(delNode.key);
}
DListNode newNode = new DListNode(key, value);
cache.put(key, newNode);
addNodeToHead(newNode);
} else {
node.value = value;
moveNodeToHead(node);
}
}
private void moveNodeToHead(DListNode node) {
removeNode(node);
addNodeToHead(node);
}
private void addNodeToHead(DListNode node) {
node.next = head.next;
node.next.prev = node;
node.prev = head;
head.next = node;
}
private void removeNode(DListNode node) {
DListNode preNode = node.prev;
DListNode nextNode = node.next;
preNode.next = nextNode;
nextNode.prev = preNode;
node.prev = null;
node.next = null;
}
private DListNode removeTailNode() {
DListNode delNode = tail.prev;
removeNode(delNode);
return delNode;
}
}
10. leetcode144 二叉树的前序遍历
10.1 代码实现1:😊递归
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
preOrder(root, res);
return res;
}
private void preOrder(TreeNode node, List<Integer> res) {
if (node == null)
return;
res.add(node.val);
preOrder(node.left, res);
preOrder(node.right, res);
}
}
10.2 代码实现2:😊迭代
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if (root == null)
return res;
Deque<TreeNode> stack = new ArrayDeque<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
res.add(node.val);
if (node.right != null) {
stack.push(node.right);
}
if (node.left != null) {
stack.push(node.left);
}
}
return res;
}
}
11. leetcode46 全排列
11.1 代码实现😊
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<Integer> path = new ArrayList<>();
List<List<Integer>> res = new ArrayList<>();
boolean[] used = new boolean[nums.length];
backtrack(nums, path, res, used);
return res;
}
private void backtrack(int[] nums,
List<Integer> path,
List<List<Integer>> res,
boolean[] used) {
if (path.size() == nums.length) {
res.add(new ArrayList<>(path));
return;
}
for (int i = 0; i < nums.length; i++) {
if (used[i])
continue;
path.add(nums[i]);
used[i] = true;
backtrack(nums, path, res, used);
path.remove(path.size() - 1);
used[i] = false;
}
}
}
12. leetcode47 全排列II
12.1 代码实现😊
class Solution {
public List<List<Integer>> permuteUnique(int[] nums) {
List<Integer> path = new ArrayList<>();
List<List<Integer>> res = new ArrayList<>();
boolean[] used = new boolean[nums.length];
Arrays.sort(nums);
backtrack(nums, path, res, used);
return res;
}
private void backtrack(int[] nums,
List<Integer> path,
List<List<Integer>> res,
boolean[] used) {
if (path.size() == nums.length) {
res.add(new ArrayList<>(path));
return;
}
for (int i = 0; i < nums.length; i++) {
if (used[i])
continue;
if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false)
continue;
path.add(nums[i]);
used[i] = true;
backtrack(nums, path, res, used);
path.remove(path.size() - 1);
used[i] = false;
}
}
}
13. leetcode141 环形链表
13.1 代码实现:😊快慢指针
// 时间复杂度:O(N)
// 空间复杂度:O(1)
public class Solution {
public boolean hasCycle(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast)
return true;
}
return false;
}
}
14. leetcode142 环形链表 II
14.1 代码实现:😊快慢指针
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) {
fast = head;
while (slow != fast) {
slow = slow.next;
fast = fast.next;
}
return slow;
}
}
return null;
}
}
15. leetcode160 相交链表
15.1 代码实现😊
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null)
return null;
ListNode pA = headA;
ListNode pB = headB;
while (pA != pB) {
pA = pA == null ? headB : pA.next;
pB = pB == null ? headA : pB.next;
}
return pA;
}
}
16. leetcode215 数组中的第K个最大元素
16.1 解题思路1:堆排序
16.2 代码实现1:😊堆排序
class Solution {
public int findKthLargest(int[] nums, int k) {
int n = nums.length;
PriorityQueue<Integer> priorityQueue;
int capacity;
if (k < n - k) {
// k比较小,构建小顶堆,寻找第 K 个最大元素
capacity = k;
priorityQueue = new PriorityQueue<>(capacity + 1);
} else {
// k比较大,构建大顶堆,寻找第 N - K + 1 个最小元素
capacity = n - k + 1;
priorityQueue =
new PriorityQueue<>(capacity + 1, ((o1, o2) -> o2 - o1));
}
for (int i = 0; i < nums.length; i++) {
priorityQueue.add(nums[i]);
if (priorityQueue.size() > capacity) {
priorityQueue.remove();
}
}
return priorityQueue.peek();
}
}
16.3 代码实现2:😊快排
class Solution {
public int findKthLargest(int[] nums, int k) {
return quickSelect(nums, 0, nums.length - 1, nums.length - k);
}
private int quickSelect(int[] nums, int low, int high, int target) {
while (true) {
int index = partition(nums, low, high);
if (index == target) {
return nums[index];
} else if (index < target) {
low = index + 1;
} else {
high = index - 1;
}
}
}
private int partition(int[] nums, int low, int high) {
int pivot = nums[low];
while (low < high) {
while (low < high && nums[high] >= pivot) {
high--;
}
nums[low] = nums[high];
while (low < high && nums[low] < pivot) {
low++;
}
nums[high] = nums[low];
}
nums[low] = pivot;
return low;
}
}
17. leetcode92 反转链表II
17.1 解题思路:头插法
17.2 代码实现😊
// 时间复杂度:O(N)
// 空间复杂度:O(1)
class Solution {
public ListNode reverseBetween(ListNode head, int left, int right) {
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode prev = dummy;
for (int i = 0; i < left - 1; i++) {
prev = prev.next;
}
ListNode curr = prev.next;
for (int i = 0; i < right - left; i++) {
ListNode next = curr.next;
curr.next = next.next;
next.next = prev.next;
prev.next = next;
}
return dummy.next;
}
}
18. leetcode103 二叉树的锯齿形层序遍历
18.1 代码实现😊
class Solution {
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if (root == null) {
return res;
}
Deque<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int level = 1;
while (!queue.isEmpty()) {
int size = queue.size();
LinkedList<Integer> levelNodes = new LinkedList<>();
boolean isLeftToRight = level % 2 == 1 ? true : false;
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
if (isLeftToRight) {
levelNodes.addLast(node.val);
} else {
levelNodes.addFirst(node.val);
}
if (node.left != null) {
queue.offer(node.left);
}
if (node.right != null) {
queue.offer(node.right);
}
}
res.add(new LinkedList<>(levelNodes));
level++;
}
return res;
}
}
19. leetcode415 字符串相加
19.1 代码实现😊
class Solution {
public String addStrings(String num1, String num2) {
StringBuilder res = new StringBuilder();
int i = num1.length() - 1;
int j = num2.length() - 1;
int carry = 0;
while (i >= 0 || j >= 0) {
int n1 = i >= 0 ? num1.charAt(i) - '0' : 0;
int n2 = j >= 0 ? num2.charAt(j) - '0' : 0;
int temp = n1 + n2 + carry;
carry = temp / 10;
res.append(temp % 10);
i--;
j--;
}
if (carry == 1)
res.append(1);
return res.reverse().toString();
}
}
20 leetcode20 有效的括号
20.1 代码实现😊
class Solution {
public boolean isValid(String s) {
Deque<Character> stack = new ArrayDeque<>();
for (char c : s.toCharArray()) {
if (c == '(')
stack.push(')');
if (c == '[')
stack.push(']');
if (c == '{')
stack.push('}');
if (c == ')' || c == ']' || c == '}') {
if (stack.isEmpty() || c != stack.pop())
return false;
}
}
return stack.isEmpty();
}
}