力扣61. 旋转链表(转vector三次翻转、成环解环)
https://leetcode-cn.com/problems/rotate-list/
给定一个链表,旋转链表,将链表每个节点向右移动 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
一、转换成vector三次翻转,再赋值回去
vector三次翻转,实现原地旋转
时间复杂度:O(n)
空间复杂度:O(n)
#include "stdafx.h"
#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;
struct ListNode
{
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
class Solution
{
public:
ListNode* rotateRight(ListNode* head, int k)
{
if (head == nullptr)return head;
//遍历,转化成vector得到长度
ListNode* lenlist = head;
vector<int>listval;
while (lenlist != nullptr)
{
listval.push_back(lenlist->val);
lenlist = lenlist->next;
}
int len = listval.size();
k = k%len;
rev(listval, 0, len - 1);
rev(listval, 0, k - 1);
rev(listval, k, len - 1);
ListNode* cur = head;
for (int i=0;i<len;i++)
{
cur->val = listval[i];
cur = cur->next;
}
return head;
}
void rev(vector<int>& listval, int begin, int end)
{
while (begin < end)
{
swap(listval[begin], listval[end]);
begin++;
end--;
}
}
};
int main()
{
Solution s;
ListNode head[5] = { 1,2,3,4,5 };
head[0].next = &head[1];
head[1].next = &head[2];
head[2].next = &head[3];
head[3].next = &head[4];
ListNode* out1 = head;
while (out1)
{
cout << out1->val << '\t';
out1 = out1->next;
}
cout << '\n';
auto result1 = s.rotateRight(head, 2);
return 0;
}
二、成环解环
既然是旋转,就与环有关。
解法思路:
- k == n 或 n == 1 时,直接返回;
- 先遍历链表求长度 n,并把链表成环;
- 根据 k 与 n 的关系决定 遍历链表的步数n - (k % n) - 1;
- 往前走 步数n - (k % n) - 1 后,当前结点 next 域置空(解环),返回后一个结点
复杂度分析
- 时间复杂度:O(N),其中 N 是链表中的元素个数
- 空间复杂度:O(1),因为只需要常数的空间
#include "stdafx.h"
#include "stdafx.h"
#include <iostream>
using namespace std;
struct ListNode
{
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
class Solution
{
public:
ListNode* rotateRight(ListNode* head, int k)
{
if (head == nullptr || head->next == nullptr)return head;
ListNode* lenlist = head;
int len = 1;
while (lenlist->next != nullptr)
{
lenlist = lenlist->next;
len++;
}
k = k%len;
//成环
lenlist->next = head;
//解环
ListNode* newend = head;
for (int i=1;i<=len-k-1;i++)
{
newend = newend->next;
}
ListNode* newhead = newend->next;
newend->next = nullptr;
return newhead;
}
};
int main()
{
Solution s;
ListNode head[5] = { 1,2,3,4,5 };
head[0].next = &head[1];
head[1].next = &head[2];
head[2].next = &head[3];
head[3].next = &head[4];
ListNode* out1 = head;
while (out1)
{
cout << out1->val << '\t';
out1 = out1->next;
}
cout << '\n';
auto result1 = s.rotateRight(head, 2);
ListNode* out2 = result1;
while (out2)
{
cout << out2->val << '\t';
out2 = out2->next;
}
cout << '\n';
return 0;
}