概述
有考察数学的,有考察操作的
题目
61.旋转链表
189. 旋转数组
725. 分隔链表
189. 旋转数组
这道题如果用 O ( n ) O(n) O(n)的空间来辅助移动那么很容易解决,这里就不贴了这个方法了
朴素旋转
按照规律移动每个元素到它应该位于的位置
class Solution {
public:
void rotate(vector<int>& nums, int k) {
k = k % nums.size();
int count = 0;// conunt表示遍历次数 当count达到nums.size()的时候 表示所有的数字都放到了正确的位置
for (int start = 0; count < nums.size(); start++) {
int current = start;
int prev = nums[start];
//用do while 因为最开始的状态也需要置换
do {
int next = (current + k) % nums.size();
swap(nums[next],prev);
current = next;
count++;
} while (start != current);
}
}
};
规律
整体逆置1次
前k个数字逆置1次
后k个数字逆置1次
搞定
1 2 3 4 5,k=1
5 4 3 2 1,前k个数字逆置
5 4 3 2 1,后k个数字逆置
5 1 2 3 4,done
如果用python答题,需要注意我们不能影响到nums的id,否则这道题怎么也AC不了
原始代码:
旋转3次
class Solution:
def rotate(self, nums: List[int], k: int) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
k = k%len(nums)
nums[:] = reversed(nums[:])
nums[:k] = reversed(nums[:k])
nums[k:] = reversed(nums[k:])
简化后的代码:
class Solution:
def rotate(self, nums: List[int], k: int) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
k = k%len(nums)
nums[:] = nums[-k:] + nums[:-k]
61. 旋转链表
二次遍历,成环+断链
首先第一趟遍历链接链表成环,统计链表节点个数
第二趟遍历第size-k-1
个结点,然后断链并返回答案
class Solution:
def rotateRight(self, head: ListNode, k: int) -> ListNode:
if not head:
return head
# 统计链表长度
size = 0
p = head
while p.next:
p = p.next
size += 1
size += 1
p.next = head # 形成环
# 走到指定位置
k = k%size
ind = size - k
t = size - k - 1
p = head
while t:
t-=1
p=p.next
ans = p.next
p.next = None # 断开链接
return ans #返回新的起始节点
逆置
如果你想沿用旋转数组的思路,也是可以的,只需要实现一个逆置链表的函数即可
就是实现长很多,也不好看
void fun(ListNode* node,ListNode* p,ListNode* q,int time)
{
int n=0;
while(n<time)
{
n++;
if(p==NULL) return;
q=p->next;
p->next=q->next;
q->next=node->next;
node->next=q;
}
}
class Solution {
public:
void fun(ListNode* node,ListNode* p,ListNode* q,int time)
{
int n=0;
while(n<time)
{
n++;
if(p==NULL) return;
q=p->next;
p->next=q->next;
q->next=node->next;
node->next=q;
}
}
ListNode* rotateRight(ListNode* head, int k) {
ListNode* temp=head;
int len=0;
while(temp)
{
len++;
temp=temp->next;
}
if(len<=1||k==0) return head;
k%=len;
ListNode* Nhead=new ListNode(0);
Nhead->next=head;
ListNode* ptr=head;
ListNode* qtr=head;
//交换整个链表
fun(Nhead,ptr,qtr,len-1);
ptr=Nhead->next;
//交换前k个链表
fun(Nhead,ptr,qtr,k-1);
ptr=Nhead;
//交换后面len-k个链表
//先找到后面链表的起始结点
for(int i=0;i<k;i++)
{
ptr=ptr->next;
}
ListNode* Nnode=ptr;
ptr=Nnode->next;
fun(Nnode,ptr,qtr,len-k-1);
return Nhead->next;
}
};