|
|
|
---
|
|
|
|
链表相关
|
|
|
|
---
|
|
|
|
|
|
|
|
[06. 从头到尾打印链表](https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/)
|
|
|
|
|
|
|
|
```java
|
|
|
|
class Solution {
|
|
|
|
public int[s] reversePrint(ListNode head) {
|
|
|
|
ListNode temp = head;
|
|
|
|
int size = 0;
|
|
|
|
while (temp != null) {
|
|
|
|
temp = temp.next;
|
|
|
|
size++;
|
|
|
|
}
|
|
|
|
int[] result = new int[size];
|
|
|
|
int index = size - 1;
|
|
|
|
while (head != null) {
|
|
|
|
result[index--] = head.val;
|
|
|
|
head = head.next;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
```java
|
|
|
|
class Solution {
|
|
|
|
public int[] reversePrint(ListNode head) {
|
|
|
|
Stack<ListNode> stack = new Stack<ListNode>();
|
|
|
|
ListNode temp = head;
|
|
|
|
while (temp != null) {
|
|
|
|
stack.push(temp);
|
|
|
|
temp = temp.next;
|
|
|
|
}
|
|
|
|
int size = stack.size();
|
|
|
|
int[] print = new int[size];
|
|
|
|
for (int i = 0; i < size; i++) {
|
|
|
|
print[i] = stack.pop().val;
|
|
|
|
}
|
|
|
|
return print;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
[22. 链表中倒数第 k 个节点](https://leetcode-cn.com/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/)
|
|
|
|
|
|
|
|
```java
|
|
|
|
class Solution {
|
|
|
|
public ListNode getKthFromEnd(ListNode head, int k) {
|
|
|
|
int length = 0;
|
|
|
|
ListNode temp = head;
|
|
|
|
while (temp != null) {
|
|
|
|
temp = temp.next;
|
|
|
|
length++;
|
|
|
|
}
|
|
|
|
for (int i = 0; i < length - k; i++) {
|
|
|
|
head = head.next;
|
|
|
|
}
|
|
|
|
return head;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
```java
|
|
|
|
class Solution {
|
|
|
|
public ListNode getKthFromEnd(ListNode head, int k) {
|
|
|
|
ListNode h0 = head;
|
|
|
|
for (int i = 0; i < k; i++) {
|
|
|
|
h0 = h0.next;
|
|
|
|
}
|
|
|
|
while (h0 != null) {
|
|
|
|
h0 = h0.next;
|
|
|
|
head = head.next;
|
|
|
|
}
|
|
|
|
return head;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
[24. 反转链表](https://leetcode-cn.com/problems/fan-zhuan-lian-biao-lcof/)
|
|
|
|
|
|
|
|
```java
|
|
|
|
class Solution {
|
|
|
|
public ListNode reverseList(ListNode head) {
|
|
|
|
if (head == null || head.next == null) {
|
|
|
|
return head;
|
|
|
|
}
|
|
|
|
ListNode h1 = head;
|
|
|
|
ListNode h2 = head.next;
|
|
|
|
ListNode h3 = null;
|
|
|
|
h1.next = null;
|
|
|
|
while (h2 != null) {
|
|
|
|
h3 = h2.next;
|
|
|
|
h2.next = h1;
|
|
|
|
h1 = h2;
|
|
|
|
h2 = h3;
|
|
|
|
}
|
|
|
|
return h1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
```java
|
|
|
|
class Solution {
|
|
|
|
public ListNode reverseList(ListNode head) {
|
|
|
|
// 递归终止条件是当前为空,或者下一个节点为空
|
|
|
|
if (head == null || head.next == null) {
|
|
|
|
return head;
|
|
|
|
}
|
|
|
|
// 这里的 h1 就是最后一个节点
|
|
|
|
ListNode h1 = reverseList(head.next);
|
|
|
|
// 如果链表是 1->2->3->4->5,那么此时的 cur 就是 5
|
|
|
|
// 而 head 是4,head的 下一个是 5,下下一个是空
|
|
|
|
// 所以 head.next.next 就是 5->4
|
|
|
|
head.next.next = head;
|
|
|
|
// 防止链表循环,需要将 head.next 设置为空
|
|
|
|
head.next = null;
|
|
|
|
// 每层递归函数都返回 h1,也就是最后一个节点
|
|
|
|
return h1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
[25. 合并两个排序的链表](https://leetcode-cn.com/problems/he-bing-liang-ge-pai-xu-de-lian-biao-lcof/)
|
|
|
|
|
|
|
|
```java
|
|
|
|
class Solution {
|
|
|
|
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
|
|
|
|
ListNode h0 = new ListNode(0);
|
|
|
|
ListNode h = h0;
|
|
|
|
while (l1 != null && l2 != null) {
|
|
|
|
if (l1.val <= l2.val) {
|
|
|
|
h0.next = l1;
|
|
|
|
l1 = l1.next;
|
|
|
|
} else {
|
|
|
|
h0.next = l2;
|
|
|
|
l2 = l2.next;
|
|
|
|
}
|
|
|
|
h0 = h0.next;
|
|
|
|
}
|
|
|
|
if (l1 == null) {
|
|
|
|
h0.next = l2;
|
|
|
|
} else {
|
|
|
|
h0.next = l1;
|
|
|
|
}
|
|
|
|
return h.next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
```java
|
|
|
|
class Solution {
|
|
|
|
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
|
|
|
|
if (l1 == null) {
|
|
|
|
return l2;
|
|
|
|
}
|
|
|
|
if (l2 == null) {
|
|
|
|
return l1;
|
|
|
|
}
|
|
|
|
if (l1.val <= l2.val) {
|
|
|
|
l1.next = mergeTwoLists(l1.next, l2);
|
|
|
|
return l1;
|
|
|
|
} else {
|
|
|
|
l2.next = mergeTwoLists(l1, l2.next);
|
|
|
|
return l2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
[35. 复杂链表的复制](https://leetcode-cn.com/problems/fu-za-lian-biao-de-fu-zhi-lcof/)
|
|
|
|
|
|
|
|
```java
|
|
|
|
class Solution {
|
|
|
|
public Node copyRandomList(Node head) {
|
|
|
|
// 存原节点和拷贝节点的一个映射
|
|
|
|
Map<Node, Node> map = new HashMap<>();
|
|
|
|
Node temp = head;
|
|
|
|
while (temp != null) {
|
|
|
|
map.put(temp, new Node(temp.val));
|
|
|
|
temp = temp.next;
|
|
|
|
}
|
|
|
|
temp = head;
|
|
|
|
while (temp != null) {
|
|
|
|
// 将拷贝节点组织成一个链表
|
|
|
|
map.get(temp).random = map.get(temp.random);
|
|
|
|
map.get(temp).next = map.get(temp.next);
|
|
|
|
temp = temp.next;
|
|
|
|
}
|
|
|
|
return map.get(head);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
```java
|
|
|
|
class Solution {
|
|
|
|
public Node copyRandomList(Node head) {
|
|
|
|
// 将拷贝节点放在原节点后面,比如 1->2 变成 1->1'->2->2'
|
|
|
|
for (Node node = head, copy = null; node != null; node = node.next.next) {
|
|
|
|
copy = new Node(node.val);
|
|
|
|
copy.next = node.next;
|
|
|
|
node.next = copy;
|
|
|
|
}
|
|
|
|
// 把拷贝节点的 random 指针安排上
|
|
|
|
for (Node node = head; node != null; node = node.next.next) {
|
|
|
|
if (node.random != null) {
|
|
|
|
node.next.random = node.random.next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Node newHead = head.next;
|
|
|
|
Node node = head;
|
|
|
|
Node temp = null;
|
|
|
|
// 分离原节点和拷贝节点
|
|
|
|
while (node != null && node.next != null) {
|
|
|
|
temp = node.next;
|
|
|
|
node.next = temp.next;
|
|
|
|
node = temp;
|
|
|
|
}
|
|
|
|
return newHead;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
[52. 两个链表的第一个公共节点](https://leetcode-cn.com/problems/liang-ge-lian-biao-de-di-yi-ge-gong-gong-jie-dian-lcof/)
|
|
|
|
|
|
|
|
```java
|
|
|
|
public class Solution {
|
|
|
|
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
|
|
|
|
ListNode h1 = headA;
|
|
|
|
ListNode h2 = headB;
|
|
|
|
while (h1 != null && h2 != null) {
|
|
|
|
if (h1 == h2) {
|
|
|
|
return h1;
|
|
|
|
}
|
|
|
|
h1 = h1.next;
|
|
|
|
h2 = h2.next;
|
|
|
|
if (h1 == null && h2 == null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
if (h1 == null) {
|
|
|
|
h1 = headB;
|
|
|
|
}
|
|
|
|
if (h2 == null) {
|
|
|
|
h2 = headA;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
```java
|
|
|
|
public class Solution {
|
|
|
|
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
|
|
|
|
ListNode h1 = headA;
|
|
|
|
ListNode h2 = headB;
|
|
|
|
while (h1 != h2) {
|
|
|
|
h1 = h1 == null ? headB : h1.next;
|
|
|
|
h2 = h2 == null ? headA : h2.next;
|
|
|
|
}
|
|
|
|
return h1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|