力扣爆刷第136天之链表七连刷(双指针快慢指针)
文章目录
一、203. 移除链表元素
题目链接:https://leetcode.cn/problems/remove-linked-list-elements/description/
思路:删除指定节点,使用双指针,一个记录前一个节点,一个记录当前节点,记录前一个节点的用于删除元素。
class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode root = new ListNode(-1, head);
ListNode pro = root, p = head;
while(p != null) {
if(p.val == val) {
pro.next = p.next;
}else{
pro = pro.next;
}
p = p.next;
}
return root.next;
}
}
二、707. 设计链表
题目链接:https://leetcode.cn/problems/design-linked-list/description/
思路:控制好边界条件就好,要相速度快用双指针就行。
class LinkNode {
int val;
LinkNode next;
public LinkNode(int val) {
this.val = val;
}
public LinkNode(int val, LinkNode node) {
this.val = val;
this.next = node;
}
}
class MyLinkedList {
LinkNode root = new LinkNode(-1);
public MyLinkedList() {
}
public int get(int index) {
LinkNode p = root;
for(int i = 0; i <= index; i++) {
if(p == null) return -1;
p = p.next;
}
if(p == null) return -1;
return p.val;
}
public void addAtHead(int val) {
LinkNode node = new LinkNode(val);
node.next = root.next;
root.next = node;
}
public void addAtTail(int val) {
LinkNode p = root;
while(p.next != null) {
p = p.next;
}
p.next = new LinkNode(val);
}
public void addAtIndex(int index, int val) {
LinkNode pro = root, p = root;
for(int i = 0; i <= index; i++) {
if(p == null) return;
pro = p;
p = p.next;
}
LinkNode node = new LinkNode(val);
pro.next = node;
node.next = p;
}
public void deleteAtIndex(int index) {
LinkNode p = root;
for(int i = 0; i < index; i++) {
if(p.next == null) return;
p = p.next;
}
if(p.next == null) return;
p.next = p.next.next;
}
}
/**
* Your MyLinkedList object will be instantiated and called as such:
* MyLinkedList obj = new MyLinkedList();
* int param_1 = obj.get(index);
* obj.addAtHead(val);
* obj.addAtTail(val);
* obj.addAtIndex(index,val);
* obj.deleteAtIndex(index);
*/
三、206. 反转链表
题目链接:https://leetcode.cn/problems/reverse-linked-list/description/
思路:头插法和尾插法都可以。随便写。
class Solution {
public ListNode reverseList(ListNode head) {
ListNode root = new ListNode();
ListNode cur = head, pre = null;
while(cur != null) {
pre = cur.next;
cur.next = root.next;
root.next = cur;
cur = pre;
}
return root.next;
}
}
四、24. 两两交换链表中的节点
题目链接:https://leetcode.cn/problems/swap-nodes-in-pairs/description/
思路:直接三个指针,pro和p和pre,前两个指针用于交换位置,后一个指针用于记录下一个交换的元素。
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode root = new ListNode(-1, head);
ListNode p1 = root, p2 = root.next;
while(p2 != null && p2.next != null) {
ListNode pre = p2.next.next;
p1.next = p2.next;
p1.next.next = p2;
p2.next = pre;
p1 = p2;
if(p2 != null) p2 = p2.next;
}
return root.next;
}
}
五、19. 删除链表的倒数第 N 个结点
题目链接:https://leetcode.cn/problems/remove-nth-node-from-end-of-list/description/
思路:快慢指针,快指针先走n步,然后再快慢指针同步走。
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode root = new ListNode(-1, head);
ListNode slow = root, fast = root;
for(int i = 0; i < n; i++) {
fast = fast.next;
}
while(fast.next != null) {
slow = slow.next;
fast = fast.next;
}
slow.next = slow.next.next;
return root.next;
}
}