向右旋转链表k个位置

对链表进行旋转

题目

给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。
示例:将如下链表向右移动2位。
在这里插入图片描述
输入:head = [1,2,3,4,5], k = 2
输出:[4,5,1,2,3]

解决思路

  • 第一步:初始时刻定义指针p指向head节点,然后让p指向链表的最后一个节点,并将链表首尾相连构成环。接着让p指向head节点。
  • 第二步:将链表向右旋转k-1步,使指向head的指针p走到最终要输出的头节点的上一个节点(注意:设链表的长度为L,向右旋转k步即让指针p从head开始,向右走L-k步)。
  • 第三步:将链表从p的下一个节点处断开,p的下一个节点即为要返回的头节点。

代码

  • C++代码
# include <stdio.h>

struct ListNode {
    int val;
    ListNode *next;
    ListNode(): val(0), next(nullptr) {}
    ListNode(int val): val(val), next(nullptr) {}
    ListNode(int val, ListNode *next): val(val), next(next) {}
};


class Solution {
public:
    ListNode* rotateRight(ListNode* head, int k) {
        if (nullptr == head || 0 == k) {
            return head;
        }

        int step  = 0;  // 记录最终实际要走的步数
        int num = 1;    // 记录链表节点的个数
        ListNode *p = head;
        // 遍历链表节点,并将指针p指向链表的尾结点
        while (p->next) {
            p = p->next;
            num += 1;
        }
        p->next = head;         // 将链表构成环,此时p指向尾节点
        p = head;               // 让p指向头节点

        step = k % num;         // 若k大于num时,链表需要转整数圈,处理后可以减少移动的步数,不需要转到一整圈
        step = num - step - 1;  // 先向右旋转k-1步(即指针向右走num-k-1步),让指针p指向最终要输出的头节点的上一个节点
        while (step--) {
            p = p->next;        // 让指针p指向最终要输出的头节点的上一个节点
        }
        
        head = p->next;         // 指针p的下一个节点即为要输出的头结点
        p->next = nullptr;      // 从p的下一个节点处断开链表
        return head;
    }
};


int main() {
    ListNode *a = new ListNode(1);
    ListNode *b = new ListNode(2);
    ListNode *c = new ListNode(3);
    ListNode *d = new ListNode(4);
    ListNode *e = new ListNode(5);
    ListNode *head = a;

    a->next = b;
    b->next = c;
    c->next = d;
    d->next = e;

    printf("before rotate: ");
    while (head) {
        printf("%d ", head->val);
        head = head->next;
    }
    printf("\n");

    int k = 2;
    head = a;
    Solution *solution = new Solution();

    ListNode *ret = solution->rotateRight(head, k);
    printf("after rotate: ");
    while (ret) {
        printf("%d ", ret->val);
        ret = ret->next;
    }

    return 0;
}
  • python代码
# -*- coding: utf-8 -*-

from typing import Optional


class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next


class Solution:
    def rotateRight(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
        if not head or 0 == k:
            return head

        step = 0        # 记录最终实际要走的步数
        num = 1         # 记录链表节点的个数
        p = head
        # 遍历链表节点,并将指针p指向链表的尾结点
        while p.next:
            p = p.next
            num += 1

        p.next = head           # 将链表构成环,此时p指向尾节点
        p = head                # 让p指向头节点
        step = k % num          # 若k大于num时,链表需要转整数圈,处理后,减少移动的步数,不需要转到一整圈
        step = num - step - 1   # 先向右旋转k-1步(即指针向右走num-k-1步),让指针p指向最终要输出的头节点的上一个节点
        while step > 0:
            p = p.next          # 让指针p指向最终要输出的头节点的上一个节点
            step -= 1

        head = p.next           # 指针p的下一个节点即为要输出的头结点
        p.next = None           # 从p的下一个节点处断开链表
        return head


def main():
    a = ListNode(1)
    b = ListNode(2)
    c = ListNode(3)
    d = ListNode(4)
    e = ListNode(5)
    head = a

    a.next = b
    b.next = c
    c.next = d
    d.next = e

    print("before rotate: ", end='')
    while head:
        print(head.val, end=' ')
        head = head.next
    print()

    head = a
    k: int = 2
    solution = Solution()
    ret = solution.rotateRight(head, k)
    print("after rotate: ", end='')
    while ret:
        print(ret.val, end=' ')
        ret = ret.next

    return


if __name__ == "__main__":
    main()

说明

  • 对应LeetCode第61题。
  • 链接:https://leetcode-cn.com/problems/rotate-list/
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值