Leetcode61 Rotate List( 旋转平移链表)

Given a linked list, rotate the list to the right by k places
where k is non-negative.
给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。
Example 1:
Input: 1->2->3->4->5->NULL, k = 2
Output: 4->5->1->2->3->NULL
Explanation:
rotate 1 steps to the right: 5->1->2->3->4->NULL
rotate 2 steps to the right: 4->5->1->2->3->NULL

Example 2:
Input: 0->1->2->NULL, k = 4
Output: 2->0->1->NULL
Explanation:
rotate 1 steps to the right: 2->0->1->NULL
rotate 2 steps to the right: 1->2->0->NULL
rotate 3 steps to the right: 0->1->2->NULL
rotate 4 steps to the right: 2->0->1->NULL
  • 双指针找位置+简单指针变化(注意k有可能大于链的长度)
  • 找到倒数k-1的位置(slow)fast先走k步(用具体的数来k)
  • 断链 、连接
解题思路
这道题的最重要的一个思路是找最后一个节点的前第k个节点!
那么我们要判断链表长度len和k的关系:
① k%len==0
这种情况直接返回head就好,因为旋转后是一样的。
② k>len
这样就要取新的k=k%len
③ k<len
以上三种情况都是为了k要小于len
然后我们找最后一个节点的前第k个节点
定义一个dummynode节点,dummynode->next=head.实际上这个dummynode是为了方便操作
而创建,为了方便对真正的头节点进行操作
定义一个fast和slow,fast是较前的一个节点,slow是较后的节点
fast先往前走k次,然后fast和slow一起走,直到fast是最后一个节点(fast->next==NULL)
12345->45123(k=2)//调整前最终fast指向5,slow指向3,分别指向两段链表的最后一个节点
后面就简单了,就是指来指去的问题了
首先,fast->next=head;//5指向1
然后,start->next=tmpRear->next;//头节点为4(slow->next)
最后,tmpRear->next=NULL;//确定尾指针

要做三件事
1确定头节点
2确定连接的位置,改动指针,连接
3确定尾节点指向空
快慢指针的原理:目标找到两段链表的尾节点,在加一个dummynode两段链表的头节点也能表示出来了。
如何找到尾节点:第二段链表表尾就是整段链表尾端。因为要移动k个位置,所以链表后k个元素一定属于第二段链表,因此倒数k+1个元素为第一段链表尾端,现在就演变成了找到倒数第k+1个节点,fast先走k步就好了

/**
 * 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 rotateRight(ListNode head, int k) {
        int len=getlen(head);
        if(head==null||k%len==0||head.next==null){
            return head;
        }
        //找到倒数k+1的位置(slow)fast先走k步、断链 、重新接起来
        ListNode slow=head;
        ListNode fast=head;
        k=k%len;
        for(int i=0;i<k;i++){//fast!=null
            if(fast==null){
                return head;
            }
            fast=fast.next;
        }
        //fast.next!=null 因此上边的for循环是k
        // 为什么(fast.next!=null,因为需要得到的是fast是最后一个节点——非空—断链的时候要用)
        while(fast.next!=null){
            fast=fast.next;
            slow=slow.next;
        }
        ListNode newhead=slow.next;
        fast.next=head;
        slow.next=null;
        return newhead;
    }
    int getlen(ListNode head){
        int len=0;
        while(head!=null){
            head=head.next;
            len++;
        }
        return len;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值