• 链表旋转


    Description

     

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

    示例 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

    Input

     

    输入包含两行,第一行为 2 个整数 n, kn,k (1 ≤ k ≤ n≤ 100000)用空格隔开,第二行为 n 个整数,用空格隔开,表示链表每一个节点的值

    Output

     

    输出单独的一行,即链表旋转后的结果,用空格隔开

    Sample Input 1 

    5 2
    1 2 3 4 5

    Sample Output 1

    4 5 1 2 3

    Sample Input 2 

    3 4
    0 1 2

    Sample Output 2

    2 0 1

    解法:

    0、定义链表的结点结构:结点中用int保存数字,用Node*指针保存下一个结点的地址。

    1、读入并构建链表。其中将第一个读入的数字放入头结点,并记录下其地址。对后续读入的n-1个结点分别构建结点并连入链表。注意最后一个结点的指针需要设置为NULL。可以在构建完成后遍历输出链表,以检查是否读入出错。

    2、进行链表旋转。链表旋转的过程就是在每一步中,将尾结点放到头结点的前面。而k次旋转操作也可以合并为将右侧的k个结点挂到头结点的前面,也可以视为将左侧的n-k个结点挂到尾结点的右侧。而如果操作次数k大于链表长度n就存在重复的操作,其中的整数*n个操作是互相抵消的。因此一共旋转的次数可以简化为k%n次,从而降低时间复杂度。

    3、遍历并输出链表。

    代码:

     1 #include "bits/stdc++.h"
     2 
     3 using namespace std;
     4 
     5 struct Node {
     6     int val;
     7     Node *pnext;
     8 };
     9 //遍历并输出节点
    10 void print(Node *head) {
    11     Node *thisNode = head;
    12     while (thisNode) {
    13         cout << thisNode->val << " ";
    14         thisNode = thisNode->pnext;
    15     }
    16 }
    17 
    18 int main() {
    19     int n, k;
    20     cin >> n >> k;
    21     //读入头结点
    22     Node *headNode = (Node *) malloc(sizeof(Node));
    23     cin >> headNode->val;
    24     Node *lastNode = headNode;
    25     //读入并构建剩余n-1个结点
    26     for (int i = 1; i < n; i++) {
    27         // create node
    28         Node *p = (Node *) malloc(sizeof(Node));
    29         cin >> p->val;
    30         lastNode->pnext = p;
    31         lastNode = p;
    32     }
    33     lastNode->pnext = NULL;    //尾结点设置为空
    34 
    35     //print(headNode);        //检查链表构建是否正确
    36 
    37     k = k % n;               //去除多余操作
    38 
    39     Node *newTailNode = headNode;       //取出左侧n-k个结点
    40     for (int i = 1; i < n - k; i++) {
    41         newTailNode = newTailNode->pnext;
    42     }
    43     Node *newHeadNode = newTailNode->pnext;
    44 
    45     //将左侧n-k个结点挂到尾结点右侧,并将新的尾节点的指针设置为NULL
    46     lastNode->pnext = headNode;
    47     newTailNode->pnext = NULL;
    48 
    49     print(newHeadNode);
    50 
    51     return 0;
    52 }
  • 相关阅读:
    About
    Git
    SQL
    fiddler
    Windows下----nvm的安装操作
    vs-code 的常用插件
    npm安装依赖时-S和-D的作用以及区别
    Node.js的安装以及包的安装使用
    JavaScript-----设计模式
    JavaScript-----JS的深拷贝和浅拷贝
  • 原文地址:https://www.cnblogs.com/gagaein/p/15338919.html
Copyright © 2020-2023  润新知