61. Rotate List。

Given a list, rotate the list to the right by k places, where k is non-negative.

For example:
Given 1->2->3->4->5->NULL and k = 2,
return 4->5->1->2->3->NULL.


这个题刚开始一直看不懂题意,不明白旋转是个什么意思。其实就是按照给定的k值将倒数k个节点移动到前面,而且这个k值大于链表总节点的时候从第一个再次开始计算。也就是题中的例子,当k是2的时候结果如此,当k的数值满足k%5=2的时候都会是这个结果。
那么明白了题意之后就会发现这道题挺简单的,只需要找到倒数第k(k对总长度取模计算)个节点就好。找到这个位置有两个思路,第一种就是先遍历一遍链表得到该链表的总长度len,然后使用len减去k得到的数值就是我们需要遍历多少个位置,需要注意的是这里我们需要根据计算出来的数值遍历节点,而很可能这个数值非常大,比如说给定:1->2->3 ,k的值为200000000,那么计算出来len为3,需要移动2000000000-3次,这样会运行超时,所以需要进行取模运算得到2,只需要遍历两次,而且无论len-k是正是负取模运算都适合。然后找到需要断开的位置之后将其断开, 并且需要将链表的尾节点和头节点连接起来。

class Solution {
public:
    ListNode* rotateRight(ListNode* head, int k) {
        if(!head) {
            return head;
        }

        int len = 1;
        ListNode* temp = head;
        while(temp->next) {//计算出总共有多少个节点
            temp = temp->next;
            len++;
        }

        temp->next = head;//将此时最后一个节点与第一个节点连接起来,然后可以直接从当前的节点进行遍历

        k = len - k;//计算出需要遍历多少个节点

        while(k%len) {//这里使用取模计算
            temp = temp->next;
            k--;
        }

        ListNode* newHead = temp->next;//新节点
        temp->next = NULL;//断开

        return newHead;
    }
};

第二种方法是使用两个指针,第一个指针先移动k次,然后第二个指针从头开始移动,当第一个指针到达为尾节点的时候,第二个指针刚好移动到总长度减去K的位置了,这种方法比较简单。但是k得值同样可能会很大,所以第一个指针移动的时候并不一定要移动k次,期间需要进行取模判断来缩小移动的次数。

class Solution {
public:
    ListNode* rotateRight(ListNode* head, int k) {
        if(!head) {
            return head;
        }

        ListNode* temp1,*temp2;
        temp1 = temp2 = head;

        int num = 0;
        while(num!=k) {//将temp1移动
            num++;
            if(!temp1->next) {//此时计算出链表的长度,并且更新k的值
                temp1 = head;
                k = k%num;//计算出余数
                num = 0;
            } else {
                temp1 = temp1->next;
            }
        }

        if(temp1 == temp2) {
            return temp1;
        } else {
            while(temp1->next) {//将temp2移动到需要断开的位置
                temp1 = temp1->next;
                temp2 = temp2->next;
            }

            ListNode* newHead = temp2->next;
            temp1->next = head;
            temp2->next = nullptr;

            return newHead;

        }
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值