61. 旋转链表 详细思路和细节解析 双指针

61. 旋转链表

给定一个链表,旋转链表,将链表每个节点向右移动 个位置,其中 是非负数。

示例 1:

输入: 1->2->3->4->5->NULL, k = 2
输出: 4->5->1->2->3->NULL
解释:
向右旋转 1 步: 5->1->2->3->4->NULL
向右旋转 2 步: 4->5->1->2->3->NULL
示例 2:

输入: 0->1->2->NULL, k = 4
输出: 2->0->1->NULL
解释:
向右旋转 1 步: 2->0->1->NULL
向右旋转 2 步: 1->2->0->NULL
向右旋转 3 步: 0->1->2->NULL
向右旋转 4 步: 2->0->1->NULL

思路

         像这种双指针的链表题目,处理一些细节处理,难点就只有一个:两指针之间的步数差。所以,首指针先走几步呢?

        有两种思路,一种是首指针要停在最后一个非空子节点,停止条件是while (first && first->next),一种是首指针要停在链表的空尾结点上,停止条件是while (first)。其实就是多走一步和少走一步的问题,具体处理跟每个人的习惯和喜好有关。

       笔者在这有一个建议,建议大家把首指针停在链表最后一个非空子节点上。原因如下:

1:首指针停在空节点上没有具体的意义,而停在链尾非空节点上,好歹知道这是链尾的有效节点。该题目就有效利用了这一信息,不然还得重新遍历找到右边链表的末节点。

2:若停在空节点上,计算首指针先走几步的时候,可能往往和实际的参数有差(例如该题的k),而这个数值,可能让你不知道它是k+1,还是k-1,或是len-k,很容易糊涂。而停在尾部非空子节点上时,分析起来相对比较明朗,不容易出错。

       这里也不是出于投机,是一个潜意识中的良好习惯,更不容易出错的一种行为方式。

解法:双指针

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
    int cntListNodes(ListNode *head) {
        if (NULL == head)
            return 0;
        
        int len = 0;
        while (head) {
            ++len;
            head = head->next;
        }

        return len;
    }
public:
    ListNode* rotateRight(ListNode* head, int k) {
        if (NULL == head || NULL == head->next || k < 1)
            return head;
        
        int len = cntListNodes(head);                    //计算长度,求实际移动位置
        k %= len;
        if (k == 0)
            return head;
        
        ListNode *first = head, *second = head;          //双指针
        while (k--)
            first = first->next;
        while (first && first->next) {                   //first要停在链表最后一个非空节点上
            first = first->next;
            second = second->next;
        }

        first->next = head;                              //将链表收尾相连,避免使用临时变量        
        head = second->next;                             //head指向新头节点
        second->next = NULL;                             //尾节点置空,防止链表成环

        return head;
    }
};

猜你喜欢

转载自blog.csdn.net/sy_123a/article/details/109122022