【CodeTop】每日练习 2025.7.1
Leetcode 92. 反转链表 II
在基础的反转链表基础上限制了范围,只需要额外处理反转段前后的指针即可。
/*** 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 reverseBetween(ListNode head, int left, int right) {ListNode dummy = new ListNode(0, head);ListNode group = dummy;for (int i = 0; i < left - 1; i++) {group = group.next;}ListNode pre = null, cur = group.next, next;ListNode temp = head.next;for (int i = 0; i < right - left + 1; i++) {next = cur.next;cur.next = pre;pre = cur;cur = next;}group.next.next = cur;group.next = pre;return dummy.next;}
}
Leetcode 141. 环形链表
经典列表找环问题,定义快慢指针,快指针每轮走两步,慢指针每轮走一步,二者最终会在入环节点处相遇。
/*** Definition for singly-linked list.* class ListNode {* int val;* ListNode next;* ListNode(int x) {* val = x;* next = null;* }* }*/
public class Solution {public boolean hasCycle(ListNode head) {ListNode slow = head, fast = head;while (fast != null && fast.next != null) {slow = slow.next;fast = fast.next.next;if (slow == fast) {return true;}}return false;}
}
Leetcode 54. 螺旋矩阵
根据题意按方向遍历,遇到越界或是已访问过的情况,改变访问节点的方向。
class Solution {private static final int[][] DIRECTIONS = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};public List<Integer> spiralOrder(int[][] matrix) {int m = matrix.length;int n = matrix[0].length;List<Integer> res = new ArrayList<>();for (int i = 0, j = 0, k = 0, direction = 0; k < m * n; k++) {res.add(matrix[i][j]);matrix[i][j] = Integer.MAX_VALUE;int x = i + DIRECTIONS[direction][0];int y = j + DIRECTIONS[direction][1];if (x < 0 || x >= m || y < 0 || y >= n || matrix[x][y] == Integer.MAX_VALUE) {direction = (direction + 1) % 4;}i += DIRECTIONS[direction][0];j += DIRECTIONS[direction][1];}return res;}
}
Leetcode 300. 最长递增子序列
可以定义 d f s ( i ) dfs(i) dfs(i) 为以 i i i 位置元素为末尾的最长子序列长度,依靠根据记忆化搜索的实现转化成动态规划。
但是这样做时间复杂度会达到 O ( N 2 ) O(N ^ 2) O(N2),其中 N N N 表示数组长度。
如果将状态定义为长度为以 i i i 位置为末尾的子序列中的最小元素值,可以结合二分查找将效率优化到 O ( N l o g N ) O(NlogN) O(NlogN)。
class Solution {public int lengthOfLIS(int[] nums) {List<Integer> dp = new ArrayList<>();for (int num : nums) {int index = binarySearch(dp, num);if (index == dp.size()) {dp.add(num);} else {dp.set(index, num);}}System.out.println(dp);}private int binarySearch(List<Integer> dp, int target) {int left = 0, right = dp.size();while (left < right) {int mid = left + ((right - left) >>> 1);if (dp.get(mid) < target) {left = mid + 1;} else {right = mid;}}return left;}
}
Leetcode 23. 合并 K 个升序链表
定义一个堆,初始状态下堆中存储每个链表的头节点元素,依次取出堆中最小的元素,并同时加入链表的后续节点,直到堆中元素全部处理完毕。
/*** 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 mergeKLists(ListNode[] lists) {PriorityQueue<ListNode> heap = new PriorityQueue<>((o1, o2) -> o1.val - o2.val);for (ListNode head : lists) {if (head != null) {heap.offer(head);}}ListNode dummy = new ListNode();ListNode cur = dummy;while (! heap.isEmpty()) {ListNode node = heap.poll();if (node.next != null) {heap.offer(node.next);}cur.next = node;cur = cur.next;}return dummy.next;}
}