数据结构与算法-链表
目录
- 25. K 个一组翻转链表 ❤️
- 92. 反转链表 II
- 23. 合并 K 个升序链表
- 143. 重排链表 ❤️
- 160. 相交链表
- 82. 删除排序链表中的重复元素 II
- 148. 排序链表
- 234. 回文链表
- 83. 删除排序链表中的重复元素
- 24. 两两交换链表中的节点 ❤️
- 138. 随机链表的复制
- 61. 旋转链表
- 补充题 1. 排序奇升偶降链表
- 86. 分隔链表
- 109. 有序链表转换二叉搜索树
- 1171. 从链表中删去总和值为零的连续节点
- 147. 对链表进行插入排序
- 369. 给单链表加一
- 1669. 合并两个链表
- 面试题 02.01. 移除重复节点
- 1367. 二叉树中的链表
- 1019. 链表中的下一个更大节点
- 725. 分隔链表
- 146. LRU 缓存
25. K 个一组翻转链表 ❤️
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
int length = 0;
for (ListNode cur = head; cur != null; cur = cur.next) {
length++;
}
ListNode dummy = new ListNode(0, head);
ListNode preGroupEnd = dummy;
while (length >= k) {
ListNode cur = preGroupEnd.next;
ListNode groupStart = cur;
ListNode pre = null;
for (int i = 0; i < k; i++) {
ListNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
// 原组头反转后变组尾,接下一组起点;上一组尾接新组头。
preGroupEnd.next = pre;
groupStart.next = cur;
preGroupEnd = groupStart;
length -= k;
}
return dummy.next;
}
}
func reverseKGroup(head *ListNode, k int) *ListNode {
length := 0
for cur := head; cur != nil; cur = cur.Next {
length++
}
dummy := &ListNode{Next: head}
preGroupEnd := dummy
for length >= k {
cur := preGroupEnd.Next
groupStart := cur
var pre *ListNode
for i := 0; i < k; i++ {
next := cur.Next
cur.Next = pre
pre = cur
cur = next
}
// 原组头反转后变组尾,接下一组起点;上一组尾接新组头。
preGroupEnd.Next = pre
groupStart.Next = cur
preGroupEnd = groupStart
length -= k
}
return dummy.Next
}
92. 反转链表 II
class Solution {
public ListNode reverseBetween(ListNode head, int left, int right) {
ListNode dummy = new ListNode(0, head);
ListNode preLeft = dummy;
for (int i = 1; i < left; i++) {
preLeft = preLeft.next;
}
ListNode cur = preLeft.next;
ListNode pre = null;
for (int i = left; i <= right; i++) {
ListNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
// 原区间头(现在的区间尾)接 right 的后继,前驱接区间新头。
preLeft.next.next = cur;
preLeft.next = pre;
return dummy.next;
}
}
func reverseBetween(head *ListNode, left int, right int) *ListNode {
dummy := &ListNode{Next: head}
preLeft := dummy
for i := 1; i < left; i++ {
preLeft = preLeft.Next
}
cur := preLeft.Next
var pre *ListNode
for i := left; i <= right; i++ {
next := cur.Next
cur.Next = pre
pre = cur
cur = next
}
// 原区间头(现在的区间尾)接 right 的后继,前驱接区间新头。
preLeft.Next.Next = cur
preLeft.Next = pre
return dummy.Next
}
23. 合并 K 个升序链表
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if (lists.length == 0) {
return null;
}
return merge(lists, 0, lists.length - 1);
}
private ListNode merge(ListNode[] lists, int lo, int hi) {
if (lo == hi) {
return lists[lo];
}
int mid = lo + (hi - lo) / 2;
return mergeTwoLists(merge(lists, lo, mid), merge(lists, mid + 1, hi));
}
private ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode();
ListNode cur = dummy;
while (l1 != null && l2 != null) {
if (l1.val <= l2.val) {
cur.next = l1;
l1 = l1.next;
} else {
cur.next = l2;
l2 = l2.next;
}
cur = cur.next;
}
cur.next = (l1 != null) ? l1 : l2;
return dummy.next;
}
}
func mergeKLists(lists []*ListNode) *ListNode {
if len(lists) == 0 {
return nil
}
if len(lists) == 1 {
return lists[0]
}
mid := len(lists) / 2
l1 := mergeKLists(lists[:mid])
l2 := mergeKLists(lists[mid:])
return mergeTwoLists(l1, l2)
}
func mergeTwoLists(l1, l2 *ListNode) *ListNode {
dummy := &ListNode{}
cur := dummy
for l1 != nil && l2 != nil {
if l1.Val <= l2.Val {
cur.Next = l1
l1 = l1.Next
} else {
cur.Next = l2
l2 = l2.Next
}
cur = cur.Next
}
// 剩余的一条整段接上即可。
if l1 != nil {
cur.Next = l1
} else {
cur.Next = l2
}
return dummy.Next
}
143. 重排链表 ❤️
class Solution {
public void reorderList(ListNode head) {
if (head == null || head.next == null) {
return;
}
// 快慢指针找中点,slow 停在前半段末尾。
ListNode slow = head, fast = head;
while (fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
}
ListNode cur = slow.next;
slow.next = null;
ListNode pre = null;
while (cur != null) {
ListNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
ListNode p1 = head, p2 = pre;
while (p2 != null) {
ListNode next1 = p1.next, next2 = p2.next;
p1.next = p2;
p2.next = next1;
p1 = next1;
p2 = next2;
}
}
}
func reorderList(head *ListNode) {
if head == nil || head.Next == nil {
return
}
// 快慢指针找中点,slow 停在前半段末尾。
slow, fast := head, head
for fast.Next != nil && fast.Next.Next != nil {
slow = slow.Next
fast = fast.Next.Next
}
cur := slow.Next
slow.Next = nil
var pre *ListNode
for cur != nil {
next := cur.Next
cur.Next = pre
pre = cur
cur = next
}
p1, p2 := head, pre
for p2 != nil {
next1, next2 := p1.Next, p2.Next
p1.Next = p2
p2.Next = next1
p1 = next1
p2 = next2
}
}
160. 相交链表
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode a = headA, b = headB;
while (a != b) {
// 走到尽头就换到另一条链的头,抹平长度差。
a = (a == null) ? headB : a.next;
b = (b == null) ? headA : b.next;
}
return a;
}
}
func getIntersectionNode(headA, headB *ListNode) *ListNode {
a, b := headA, headB
for a != b {
// 走到尽头就换到另一条链的头,抹平长度差。
if a == nil {
a = headB
} else {
a = a.Next
}
if b == nil {
b = headA
} else {
b = b.Next
}
}
return a
}
82. 删除排序链表中的重复元素 II
class Solution {
public ListNode deleteDuplicates(ListNode head) {
ListNode dummy = new ListNode(0, head);
ListNode pre = dummy, cur = head;
while (cur != null) {
boolean isDuplicate = false;
while (cur.next != null && cur.next.val == cur.val) {
cur = cur.next;
isDuplicate = true;
}
if (isDuplicate) {
// 整段重复值一个不留。
pre.next = cur.next;
} else {
pre = cur;
}
cur = cur.next;
}
return dummy.next;
}
}
func deleteDuplicates(head *ListNode) *ListNode {
dummy := &ListNode{Next: head}
pre, cur := dummy, head
for cur != nil {
isDuplicate := false
for cur.Next != nil && cur.Next.Val == cur.Val {
cur = cur.Next
isDuplicate = true
}
if isDuplicate {
// 整段重复值一个不留。
pre.Next = cur.Next
} else {
pre = cur
}
cur = cur.Next
}
return dummy.Next
}
148. 排序链表
class Solution {
public ListNode sortList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
// 从 dummy 出发找中点,保证两节点时拆成 1 + 1。
ListNode dummy = new ListNode(0, head);
ListNode slow = dummy, fast = dummy;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
ListNode rightHead = slow.next;
slow.next = null;
ListNode l1 = sortList(head);
ListNode l2 = sortList(rightHead);
return mergeTwoLists(l1, l2);
}
private ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode();
ListNode cur = dummy;
while (l1 != null && l2 != null) {
if (l1.val <= l2.val) {
cur.next = l1;
l1 = l1.next;
} else {
cur.next = l2;
l2 = l2.next;
}
cur = cur.next;
}
cur.next = (l1 != null) ? l1 : l2;
return dummy.next;
}
}
func sortList(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
}
// 从 dummy 出发找中点,保证两节点时拆成 1 + 1。
dummy := &ListNode{Next: head}
slow, fast := dummy, dummy
for fast != nil && fast.Next != nil {
slow = slow.Next
fast = fast.Next.Next
}
rightHead := slow.Next
slow.Next = nil
l1 := sortList(head)
l2 := sortList(rightHead)
return mergeSorted(l1, l2)
}
func mergeSorted(l1, l2 *ListNode) *ListNode {
dummy := &ListNode{}
cur := dummy
for l1 != nil && l2 != nil {
if l1.Val <= l2.Val {
cur.Next = l1
l1 = l1.Next
} else {
cur.Next = l2
l2 = l2.Next
}
cur = cur.Next
}
if l1 != nil {
cur.Next = l1
} else {
cur.Next = l2
}
return dummy.Next
}
234. 回文链表
class Solution {
public boolean isPalindrome(ListNode head) {
if (head == null || head.next == null) {
return true;
}
ListNode slow = head, fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
// 反转后半段。
ListNode pre = null, cur = slow;
while (cur != null) {
ListNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
ListNode left = head, right = pre;
while (right != null) {
if (left.val != right.val) {
return false;
}
left = left.next;
right = right.next;
}
return true;
}
}
func isPalindrome(head *ListNode) bool {
if head == nil || head.Next == nil {
return true
}
slow, fast := head, head
for fast != nil && fast.Next != nil {
slow = slow.Next
fast = fast.Next.Next
}
// 反转后半段。
var pre *ListNode
cur := slow
for cur != nil {
next := cur.Next
cur.Next = pre
pre = cur
cur = next
}
left, right := head, pre
for right != nil {
if left.Val != right.Val {
return false
}
left = left.Next
right = right.Next
}
return true
}
83. 删除排序链表中的重复元素
class Solution {
public ListNode deleteDuplicates(ListNode head) {
ListNode cur = head;
while (cur != null && cur.next != null) {
if (cur.next.val == cur.val) {
// 跳过重复节点,cur 原地不动继续检查新的后继。
cur.next = cur.next.next;
} else {
cur = cur.next;
}
}
return head;
}
}
func deleteDuplicates(head *ListNode) *ListNode {
cur := head
for cur != nil && cur.Next != nil {
if cur.Next.Val == cur.Val {
// 跳过重复节点,cur 原地不动继续检查新的后继。
cur.Next = cur.Next.Next
} else {
cur = cur.Next
}
}
return head
}
24. 两两交换链表中的节点 ❤️
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dummy = new ListNode(0, head);
ListNode pre = dummy;
while (pre.next != null && pre.next.next != null) {
ListNode first = pre.next;
ListNode second = first.next;
// 三步换指针,顺序不能乱。
first.next = second.next;
second.next = first;
pre.next = second;
pre = first;
}
return dummy.next;
}
}
func swapPairs(head *ListNode) *ListNode {
dummy := &ListNode{Next: head}
pre := dummy
for pre.Next != nil && pre.Next.Next != nil {
first := pre.Next
second := first.Next
// 三步换指针,顺序不能乱。
first.Next = second.Next
second.Next = first
pre.Next = second
pre = first
}
return dummy.Next
}
138. 随机链表的复制
class Solution {
public Node copyRandomList(Node head) {
if (head == null) {
return null;
}
// 第一步:每个原节点后插入拷贝节点。
for (Node cur = head; cur != null; cur = cur.next.next) {
Node copy = new Node(cur.val);
copy.next = cur.next;
cur.next = copy;
}
// 第二步:拷贝节点的 random 是原 random 的下一个节点。
for (Node cur = head; cur != null; cur = cur.next.next) {
if (cur.random != null) {
cur.next.random = cur.random.next;
}
}
// 第三步:拆分两条链,原链要复原。
Node newHead = head.next;
for (Node cur = head; cur != null; cur = cur.next) {
Node copy = cur.next;
cur.next = copy.next;
copy.next = (copy.next != null) ? copy.next.next : null;
}
return newHead;
}
}
func copyRandomList(head *Node) *Node {
if head == nil {
return nil
}
// 第一步:每个原节点后插入拷贝节点。
for cur := head; cur != nil; cur = cur.Next.Next {
copy := &Node{Val: cur.Val, Next: cur.Next}
cur.Next = copy
}
// 第二步:拷贝节点的 random 是原 random 的下一个节点。
for cur := head; cur != nil; cur = cur.Next.Next {
if cur.Random != nil {
cur.Next.Random = cur.Random.Next
}
}
// 第三步:拆分两条链,原链要复原。
newHead := head.Next
for cur := head; cur != nil; cur = cur.Next {
copy := cur.Next
cur.Next = copy.Next
if copy.Next != nil {
copy.Next = copy.Next.Next
}
}
return newHead
}
61. 旋转链表
class Solution {
public ListNode rotateRight(ListNode head, int k) {
if (head == null || head.next == null || k == 0) {
return head;
}
int length = 1;
ListNode tail = head;
while (tail.next != null) {
length++;
tail = tail.next;
}
k %= length;
if (k == 0) {
return head;
}
// 成环后从原尾走 length - k 步到新尾。
tail.next = head;
for (int i = 0; i < length - k; i++) {
tail = tail.next;
}
ListNode newHead = tail.next;
tail.next = null;
return newHead;
}
}
func rotateRight(head *ListNode, k int) *ListNode {
if head == nil || head.Next == nil || k == 0 {
return head
}
length := 1
tail := head
for tail.Next != nil {
length++
tail = tail.Next
}
k %= length
if k == 0 {
return head
}
// 成环后从原尾走 length - k 步到新尾。
tail.Next = head
for i := 0; i < length-k; i++ {
tail = tail.Next
}
newHead := tail.Next
tail.Next = nil
return newHead
}
补充题 1. 排序奇升偶降链表
class Solution {
public ListNode sortOddEvenList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
// 拆成奇偶两条链。
ListNode odd = head, even = head.next;
ListNode evenHead = even;
while (even != null && even.next != null) {
odd.next = odd.next.next;
odd = odd.next;
even.next = even.next.next;
even = even.next;
}
odd.next = null; // 断尾,防止成环。
// 反转偶数链,使其升序。
ListNode pre = null, cur = evenHead;
while (cur != null) {
ListNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
// 合并两个有序链表。
ListNode dummy = new ListNode();
ListNode tail = dummy;
ListNode l1 = head, l2 = pre;
while (l1 != null && l2 != null) {
if (l1.val <= l2.val) {
tail.next = l1;
l1 = l1.next;
} else {
tail.next = l2;
l2 = l2.next;
}
tail = tail.next;
}
tail.next = (l1 != null) ? l1 : l2;
return dummy.next;
}
}
func sortOddEvenList(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
}
// 拆成奇偶两条链。
odd, even := head, head.Next
evenHead := even
for even != nil && even.Next != nil {
odd.Next = odd.Next.Next
odd = odd.Next
even.Next = even.Next.Next
even = even.Next
}
odd.Next = nil // 断尾,防止成环。
// 反转偶数链,使其升序。
var pre *ListNode
cur := evenHead
for cur != nil {
next := cur.Next
cur.Next = pre
pre = cur
cur = next
}
// 合并两个有序链表。
dummy := &ListNode{}
tail := dummy
l1, l2 := head, pre
for l1 != nil && l2 != nil {
if l1.Val <= l2.Val {
tail.Next = l1
l1 = l1.Next
} else {
tail.Next = l2
l2 = l2.Next
}
tail = tail.Next
}
if l1 != nil {
tail.Next = l1
} else {
tail.Next = l2
}
return dummy.Next
}
86. 分隔链表
class Solution {
public ListNode partition(ListNode head, int x) {
ListNode smallDummy = new ListNode();
ListNode largeDummy = new ListNode();
ListNode small = smallDummy, large = largeDummy;
for (ListNode cur = head; cur != null; cur = cur.next) {
if (cur.val < x) {
small.next = cur;
small = small.next;
} else {
large.next = cur;
large = large.next;
}
}
large.next = null; // 断尾,防止成环。
small.next = largeDummy.next;
return smallDummy.next;
}
}
func partition(head *ListNode, x int) *ListNode {
smallDummy := &ListNode{}
largeDummy := &ListNode{}
small, large := smallDummy, largeDummy
for cur := head; cur != nil; cur = cur.Next {
if cur.Val < x {
small.Next = cur
small = small.Next
} else {
large.Next = cur
large = large.Next
}
}
large.Next = nil // 断尾,防止成环。
small.Next = largeDummy.Next
return smallDummy.Next
}
109. 有序链表转换二叉搜索树
class Solution {
public TreeNode sortedListToBST(ListNode head) {
if (head == null) {
return null;
}
ListNode mid = findMiddle(head);
TreeNode root = new TreeNode(mid.val);
if (head == mid) {
return root; // 只剩一个节点,避免死递归。
}
root.left = sortedListToBST(head);
root.right = sortedListToBST(mid.next);
return root;
}
private ListNode findMiddle(ListNode head) {
ListNode pre = null;
ListNode slow = head, fast = head;
while (fast != null && fast.next != null) {
pre = slow;
slow = slow.next;
fast = fast.next.next;
}
if (pre != null) {
pre.next = null; // 从中点前切断。
}
return slow;
}
}
func sortedListToBST(head *ListNode) *TreeNode {
if head == nil {
return nil
}
mid := findMiddle(head)
root := &TreeNode{Val: mid.Val}
if head == mid {
return root // 只剩一个节点,避免死递归。
}
root.Left = sortedListToBST(head)
root.Right = sortedListToBST(mid.Next)
return root
}
func findMiddle(head *ListNode) *ListNode {
var pre *ListNode
slow, fast := head, head
for fast != nil && fast.Next != nil {
pre = slow
slow = slow.Next
fast = fast.Next.Next
}
if pre != nil {
pre.Next = nil // 从中点前切断。
}
return slow
}
1171. 从链表中删去总和值为零的连续节点
class Solution {
public ListNode removeZeroSumSublists(ListNode head) {
ListNode dummy = new ListNode(0, head);
Map<Integer, ListNode> lastSeen = new HashMap<>();
int prefixSum = 0;
for (ListNode cur = dummy; cur != null; cur = cur.next) {
prefixSum += cur.val;
lastSeen.put(prefixSum, cur); // 记录前缀和最后出现的节点。
}
prefixSum = 0;
for (ListNode cur = dummy; cur != null; cur = cur.next) {
prefixSum += cur.val;
cur.next = lastSeen.get(prefixSum).next;
}
return dummy.next;
}
}
func removeZeroSumSublists(head *ListNode) *ListNode {
dummy := &ListNode{Next: head}
lastSeen := make(map[int]*ListNode)
prefixSum := 0
for cur := dummy; cur != nil; cur = cur.Next {
prefixSum += cur.Val
lastSeen[prefixSum] = cur // 记录前缀和最后出现的节点。
}
prefixSum = 0
for cur := dummy; cur != nil; cur = cur.Next {
prefixSum += cur.Val
cur.Next = lastSeen[prefixSum].Next
}
return dummy.Next
}
147. 对链表进行插入排序
class Solution {
public ListNode insertionSortList(ListNode head) {
ListNode dummy = new ListNode();
ListNode cur = head;
while (cur != null) {
ListNode next = cur.next; // 先存后继,插入会改掉它。
ListNode pre = dummy;
while (pre.next != null && pre.next.val < cur.val) {
pre = pre.next;
}
cur.next = pre.next;
pre.next = cur;
cur = next;
}
return dummy.next;
}
}
func insertionSortList(head *ListNode) *ListNode {
dummy := &ListNode{}
cur := head
for cur != nil {
next := cur.Next // 先存后继,插入会改掉它。
pre := dummy
for pre.Next != nil && pre.Next.Val < cur.Val {
pre = pre.Next
}
cur.Next = pre.Next
pre.Next = cur
cur = next
}
return dummy.Next
}
369. 给单链表加一
class Solution {
public ListNode plusOne(ListNode head) {
Deque<Integer> stack = new ArrayDeque<>();
for (ListNode cur = head; cur != null; cur = cur.next) {
stack.push(cur.val);
}
int carry = 1;
ListNode newHead = null;
while (!stack.isEmpty() || carry > 0) {
int sum = carry + (stack.isEmpty() ? 0 : stack.pop());
carry = sum / 10;
// 头插法:低位先建,挂在结果链前面。
newHead = new ListNode(sum % 10, newHead);
}
return newHead;
}
}
func plusOne(head *ListNode) *ListNode {
var stack []int
for cur := head; cur != nil; cur = cur.Next {
stack = append(stack, cur.Val)
}
carry := 1
var newHead *ListNode
for len(stack) > 0 || carry > 0 {
sum := carry
if len(stack) > 0 {
sum += stack[len(stack)-1]
stack = stack[:len(stack)-1]
}
carry = sum / 10
// 头插法:低位先建,挂在结果链前面。
newHead = &ListNode{Val: sum % 10, Next: newHead}
}
return newHead
}
1669. 合并两个链表
class Solution {
public ListNode mergeInBetween(ListNode list1, int a, int b, ListNode list2) {
ListNode dummy = new ListNode(0, list1);
ListNode preA = dummy, afterB = dummy;
for (int i = 0; i < a; i++) {
preA = preA.next;
}
for (int i = 0; i < b + 2; i++) {
afterB = afterB.next;
}
preA.next = list2;
ListNode tail = list2;
while (tail.next != null) {
tail = tail.next;
}
tail.next = afterB;
return dummy.next;
}
}
func mergeInBetween(list1 *ListNode, a int, b int, list2 *ListNode) *ListNode {
dummy := &ListNode{Next: list1}
preA, afterB := dummy, dummy
for i := 0; i < a; i++ {
preA = preA.Next
}
for i := 0; i < b+2; i++ {
afterB = afterB.Next
}
preA.Next = list2
tail := list2
for tail.Next != nil {
tail = tail.Next
}
tail.Next = afterB
return dummy.Next
}
面试题 02.01. 移除重复节点
class Solution {
public ListNode removeDuplicateNodes(ListNode head) {
if (head == null) {
return null;
}
Set<Integer> seen = new HashSet<>();
seen.add(head.val);
ListNode pre = head;
while (pre.next != null) {
if (seen.add(pre.next.val)) {
pre = pre.next;
} else {
// 值已出现,删掉后继节点。
pre.next = pre.next.next;
}
}
return head;
}
}
func removeDuplicateNodes(head *ListNode) *ListNode {
if head == nil {
return nil
}
seen := map[int]bool{head.Val: true}
pre := head
for pre.Next != nil {
if seen[pre.Next.Val] {
// 值已出现,删掉后继节点。
pre.Next = pre.Next.Next
} else {
seen[pre.Next.Val] = true
pre = pre.Next
}
}
return head
}
1367. 二叉树中的链表
class Solution {
public boolean isSubPath(ListNode head, TreeNode root) {
if (root == null) {
return false;
}
// 以 root 为起点匹配,或换到左右子树找新起点。
return dfs(root, head) || isSubPath(head, root.left) || isSubPath(head, root.right);
}
private boolean dfs(TreeNode node, ListNode cur) {
if (cur == null) {
return true;
}
if (node == null || node.val != cur.val) {
return false;
}
return dfs(node.left, cur.next) || dfs(node.right, cur.next);
}
}
func isSubPath(head *ListNode, root *TreeNode) bool {
if root == nil {
return false
}
var dfs func(node *TreeNode, cur *ListNode) bool
dfs = func(node *TreeNode, cur *ListNode) bool {
if cur == nil {
return true
}
if node == nil || node.Val != cur.Val {
return false
}
return dfs(node.Left, cur.Next) || dfs(node.Right, cur.Next)
}
// 以 root 为起点匹配,或换到左右子树找新起点。
return dfs(root, head) || isSubPath(head, root.Left) || isSubPath(head, root.Right)
}
1019. 链表中的下一个更大节点
class Solution {
public int[] nextLargerNodes(ListNode head) {
List<Integer> nums = new ArrayList<>();
for (ListNode cur = head; cur != null; cur = cur.next) {
nums.add(cur.val);
}
int[] res = new int[nums.size()];
Deque<Integer> stack = new ArrayDeque<>(); // 单调递减栈,存下标。
for (int i = 0; i < nums.size(); i++) {
while (!stack.isEmpty() && nums.get(i) > nums.get(stack.peek())) {
res[stack.pop()] = nums.get(i);
}
stack.push(i);
}
return res;
}
}
func nextLargerNodes(head *ListNode) []int {
var nums []int
for cur := head; cur != nil; cur = cur.Next {
nums = append(nums, cur.Val)
}
res := make([]int, len(nums))
var stack []int // 单调递减栈,存下标。
for i, num := range nums {
for len(stack) > 0 && num > nums[stack[len(stack)-1]] {
res[stack[len(stack)-1]] = num
stack = stack[:len(stack)-1]
}
stack = append(stack, i)
}
return res
}
725. 分隔链表
class Solution {
public ListNode[] splitListToParts(ListNode head, int k) {
int length = 0;
for (ListNode cur = head; cur != null; cur = cur.next) {
length++;
}
int partSize = length / k;
int extra = length % k; // 前 extra 段各多一个节点。
ListNode[] res = new ListNode[k];
ListNode cur = head;
for (int i = 0; i < k && cur != null; i++) {
res[i] = cur;
int size = partSize + (i < extra ? 1 : 0);
for (int j = 1; j < size; j++) {
cur = cur.next;
}
ListNode next = cur.next;
cur.next = null;
cur = next;
}
return res;
}
}
func splitListToParts(head *ListNode, k int) []*ListNode {
length := 0
for cur := head; cur != nil; cur = cur.Next {
length++
}
partSize := length / k
extra := length % k // 前 extra 段各多一个节点。
res := make([]*ListNode, k)
cur := head
for i := 0; i < k && cur != nil; i++ {
res[i] = cur
size := partSize
if i < extra {
size++
}
for j := 1; j < size; j++ {
cur = cur.Next
}
next := cur.Next
cur.Next = nil
cur = next
}
return res
}
146. LRU 缓存
class LRUCache {
private static class Node {
int key, value;
Node prev, next;
Node() {}
Node(int key, int value) {
this.key = key;
this.value = value;
}
}
private final int capacity;
private final Map<Integer, Node> cache = new HashMap<>();
private final Node head = new Node(); // 头尾哨兵,免去判空。
private final Node tail = new Node();
public LRUCache(int capacity) {
this.capacity = capacity;
head.next = tail;
tail.prev = head;
}
public int get(int key) {
Node node = cache.get(key);
if (node == null) {
return -1;
}
moveToHead(node);
return node.value;
}
public void put(int key, int value) {
Node node = cache.get(key);
if (node != null) {
node.value = value;
moveToHead(node);
return;
}
Node newNode = new Node(key, value);
cache.put(key, newNode);
addToHead(newNode);
if (cache.size() > capacity) {
Node removed = removeTail();
cache.remove(removed.key);
}
}
private void moveToHead(Node node) {
removeNode(node);
addToHead(node);
}
private void addToHead(Node node) {
node.prev = head;
node.next = head.next;
head.next.prev = node;
head.next = node;
}
private void removeNode(Node node) {
node.prev.next = node.next;
node.next.prev = node.prev;
}
private Node removeTail() {
Node node = tail.prev;
removeNode(node);
return node;
}
}
type Node struct {
key, value int
prev, next *Node
}
type LRUCache struct {
capacity int
cache map[int]*Node
head, tail *Node // 头尾哨兵,免去判空。
}
func Constructor(capacity int) LRUCache {
head, tail := &Node{}, &Node{}
head.next = tail
tail.prev = head
return LRUCache{
capacity: capacity,
cache: make(map[int]*Node),
head: head,
tail: tail,
}
}
func (c *LRUCache) Get(key int) int {
node, ok := c.cache[key]
if !ok {
return -1
}
c.moveToHead(node)
return node.value
}
func (c *LRUCache) Put(key int, value int) {
if node, ok := c.cache[key]; ok {
node.value = value
c.moveToHead(node)
return
}
newNode := &Node{key: key, value: value}
c.cache[key] = newNode
c.addToHead(newNode)
if len(c.cache) > c.capacity {
removed := c.removeTail()
delete(c.cache, removed.key)
}
}
func (c *LRUCache) moveToHead(node *Node) {
c.removeNode(node)
c.addToHead(node)
}
func (c *LRUCache) addToHead(node *Node) {
node.prev = c.head
node.next = c.head.next
c.head.next.prev = node
c.head.next = node
}
func (c *LRUCache) removeNode(node *Node) {
node.prev.next = node.next
node.next.prev = node.prev
}
func (c *LRUCache) removeTail() *Node {
node := c.tail.prev
c.removeNode(node)
return node
}