我一直觉得双指针是一个非常好用的方法,在链表中可以使用,在数组中依然可以,很灵活。
1. 寻找中间结点
用两个指针 slow 与 fast 一起遍历链表。slow 一次走一步, fast 一次走两步。那么当 fast 到达链表的末尾时,slow 必然位于中间。
public ListNode middleNode(ListNode head) {
ListNode slow = head. fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
2. 寻找倒数第K个元素
在这里最重要的思想就是先将fast向后遍历到第k + 1 个结点,slow 仍然指向链表的第一个结点,此时指针fast 与 slow 二者之间刚好间隔 k 个结点。之后两个指针同步向后走,当 fast 走到链表的尾部空节点时,slow 指针刚好指向链表的倒数第K个结点。
这样就很巧妙,主要是思想要理解。
要注意的一点,链表的长度可能小于k,寻找k位置的时候必须判断fast是否为null
public ListNode getKthFromEnd(ListNode head, int k) {
ListNode fast = head;
ListNode slow = head;
while (fast != null && k > 0) {
fast = fast.next;
k--;
}
while (fast != null) {
fast = fast.next;
slow = slow.next;
}
return slow;
}
3. 旋转链表
还是双指针,找到倒数k的位置,也就是两段分割的位置,再将两个链表拼接。文章来源:https://www.toymoban.com/news/detail-609371.html
k有可能大于链表长度,所以首先获取一下链表长度len,如果然后k=k % len,如果k == 0,就不用旋转,直接返回头结点。文章来源地址https://www.toymoban.com/news/detail-609371.html
public ListNode rotateRight(ListNode head, int k) {
if (head == null || k == 0) {
return head;
}
ListNode temp = head;
ListNode slow = head;
ListNode fast = head;
int len = 0;
while (head != null) {
head = head.next;
len++;
}
if (k % len == 0) {
return temp;
}
while ((k % len) > 0) {
k--;
fast = fast.next;
}
while (fast.next != null) {
fast = fast.next;
slow = slow.next;
}
ListNode res = slow.next;
slow.next = null;
fast.next = temp;
return res;
}
到了这里,关于算法通关村第一关——链表经典问题之双指针专题笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!