一.寻找中间节点
题目:leetcode876
给你单链表的头结点 head
,请你找出并返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。
思路:使用快慢指针,设置一个虚拟节点,两个指针同时指向head,这两个指针一起遍历链表,快指针一次走两步,慢指针一次走一步,当快指针位于链表的末尾时,慢指针位于链表的中间,即中间节点。
代码:
class Solution {
public ListNode middleNode(ListNode head) {
ListNode fast=head;
ListNode slow=head;
while(fast!=null&&fast.next!=null){
fast=fast.next;
fast=fast.next;
slow=slow.next;
}
return slow;
}
}
二.寻找倒数第k个元素
题目:给定一个头节点为 head
的链表用于记录一系列核心肌群训练项目编号,请查找并返回倒数第 cnt
个训练项目编号。
思路:同样使用快慢指针(fast和slow),现将fast向后移动,指向第k+1个节点,slow仍然指向头节点,此时两个节点之间相差k个节点接着将两个指针同时向后遍历,当fast指向链表的空节点时,slow走到链表的倒数第k个节点。
代码:
class Solution {
public ListNode trainingPlan(ListNode head, int cnt) {
ListNode fast=head;
ListNode slow=head;
int i=0;
while(i<cnt){
fast=fast.next;
i++;
}
while(fast!=null){
fast=fast.next;
slow=slow.next;
}
return slow;
}
}
三.旋转链表
题目:给你一个链表的头节点 head
,旋转链表,将链表每个节点向右移动 k
个位置。
思路:首先声明一个指针head1作为返回的头节点,接着设一个中间节点指向第k个位置,接着将首节点移动到末尾节点的下一位,返回第k个节点。
代码:
class Solution {
public ListNode rotateRight(ListNode head, int k) {
if(head==null||head.next==null||k==0){
return head;
}
ListNode head1;
ListNode tail=head;
ListNode temp=head;
int length=1;
while(tail.next!=null){
tail=tail.next;
length++;
}
int kk=(k%length);
if(kk==0){
return head;
}
int len=length-kk;
while(len>1){
temp=temp.next;
len--;
}
head1=temp.next;
temp.next=null;
tail.next=head;
return head1;
}
}