链表
文章目录
1、在链表中穿针引线
LeetCode 206. 反转链表
206反转链表
剑指offer24
反转一个链表,节点的值不变 只是节点的next指针发生改变
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
if(head == null) return null;
ListNode pre = null;
ListNode cur = head;
while (cur != null ) {
// 从后往前开始改变
ListNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
}
}
拓展:
Reverse Linked List II
Remove Duplicates from Sorted List
Partition List
Odd Even Linked List
LeetCode 2. 两数相加
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode pre = new ListNode(0);
ListNode cur = pre;
int carry = 0;
while(l1 != null || l2 != null) {
int x = l1 == null ? 0 : l1.val;
int y = l2 == null ? 0 : l2.val;
int sum = x + y + carry;
carry = sum / 10;
sum = sum % 10;
cur.next = new ListNode(sum);
cur = cur.next;
if(l1 != null)
l1 = l1.next;
if(l2 != null)
l2 = l2.next;
}
if(carry == 1) {
cur.next = new ListNode(carry);
}
return pre.next;
}
}
- Add Two Numbers II
2、设立链表的虚拟头结点
LeetCode 203. 移除列表元素
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode removeElements(ListNode head, int val) {
// if(head == null) return null;
while(head != null && head.val == val) {
head = head.next;
}
if(head == null) return null;
ListNode cur = head;
while(cur.next != null) {
if(cur.next.val == val){
ListNode delNode = cur.next;
cur.next = delNode.next;
}else cur = cur.next;
}
return head;
}
}
// 虚拟节点
class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode dummyNode = new ListNode(0);
dummyNode.next = head;
ListNode cur = dummyNode;
while(cur.next != null ) {
if(cur.next.val == val) {
cur.next = cur.next.next;
}
else cur = cur.next;
}
return dummyNode.next;
}
}
拓展:
Remove Duplicates from Sorted List II
Merge Two Sorted Lists
LeetCode 24. 交换节点成对
/**
* 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 swapPairs(ListNode head) {
if(head == null) return head;
if(head.next == null) return head;
ListNode dummyNode = new ListNode(0);
dummyNode.next = head;
ListNode p = dummyNode;// 操作指针
while(p.next != null && p.next.next != null) {
ListNode node1 = p.next;
ListNode node2 = node1.next;
ListNode next = node2.next;
node2.next = node1;
node1.next = next;
p.next = node2;
p = node1;
}
return dummyNode.next;
}
}
扩展:
Reverse Nodes in k-Group
Insertion Sort List
Sort List
3、不仅仅是穿针引线
LeetCode 237. 删除列表中的节点
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public void deleteNode(ListNode node) {
if(node == null) return;
if(node.next == null) {
node = null;
return;
}
node.val = node.next.val;
node.next = node.next.next;
}
}
4、双指针技术
LeetCode 19. 删除列表的倒数第N个节点
解法1:先遍历- -遍计算链表长度;再遍历- -遍删除倒数第n个节点
解法2:双指针+虚拟节点
/**
* 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 removeNthFromEnd(ListNode head, int n) {
ListNode dummyHead = new ListNode(0);
dummyHead.next = head;
ListNode p = dummyHead;
ListNode q = dummyHead;
for (int i = 0; i < n + 1;i++) {
q = q.next;
}
while(q != null) {
p = p.next;
q = q.next;
}
ListNode delNode = p.next;
p.next = delNode.next;
return dummyHead.next;
}
}
剑指offer 52 两个链表的第一个公共节点
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
int lenA = calLen(headA);
int lenB = calLen(headB);
int sub = Math.abs(lenA - lenB);
ListNode curA = headA;
ListNode curB = headB;
if(lenA > lenB) return compareNode(headA,headB,sub);
else return compareNode(headB,headA,sub);
}
// head1更长
private ListNode compareNode(ListNode head1,ListNode head2,int sub) {
ListNode curA = head1;
ListNode curB = head2;
while(sub > 0) {
sub --;
curA = curA.next;
}
while(curA != null) {
if(curA == curB) return curA;
else{
curA = curA.next;
curB = curB.next;
}
}
return null;
}
private int calLen(ListNode head ) {
if(head == null) return 0;
int res = 0;
while(head != null ) {
res++;
head = head.next;
}
return res;
}
}
5、复制复杂链表(HashMap)
剑指offer 35 复杂链表的复制
/*
// Definition for a Node.
class Node {
int val;
Node next;
Node random;
public Node(int val) {
this.val = val;
this.next = null;
this.random = null;
}
}
*/
class Solution {
public Node copyRandomList(Node head) {
if(head == null) return head;
Map<Node, Node> map = new HashMap<>();
Node cur = head;
while(cur != null) {
map.put(cur, new Node(cur.val));
cur = cur.next;
}
cur = head;
while(cur != null) {
map.get(cur).next = map.get(cur.next);
map.get(cur).random = map.get(cur.random);
cur = cur.next;
}
return map.get(head);
}
}