将给定的链表向右转动k个位置,k是非负数。
例如:
给定1->2->3->4->5->null , k=2,
返回4->5->1->2->3->null。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
/*
题目;给定一个链表,将链表旋转到右边的k个位置,其中k是非负的。
例如:
1->2->3->4->5->NULL,为K = 2,
返还4->5->1->2->3->NULL。
*/
/*
分析:先遍历一遍,得出链表长度len,注意k可能会大于len,因此k%=len。
将尾结点next指针指向首节点,形成一个环,接着往后跑len-k步,从这里断开,就是结果
*/
class Solution {
public:
ListNode *rotateRight(ListNode *head, int k) {
if(head==nullptr||k==0)
return head;
int len=1;
ListNode *p=head;
while(p->next){
//遍历一遍,求出链表长度
len++;
p=p->next;
}
k=len-k%len;
p->next=head;//首尾相连
for(int step=0;step<k;step++){
p=p->next;//接着往后跑
}
head=p->next;//新的首节点
p->next=nullptr;//断开环
return head;
}
}; package go.jacob.day817; /** * 61. Rotate List * @author Jacob */ public class Demo2 { /* * 这种方法考虑了k=0的情况。 * 当k=0,cur和pre都为链表最后一个节点 * 运行cur.next = preHead.next;preHead.next = pre.next;pre.next = null;后 * 链表结构没有改变 */ public ListNode rotateRight(ListNode head, int k) { if (k == 0 || head == null || head.next == null) return head; ListNode preHead = new ListNode(0); preHead.next = head; ListNode cur = head; ListNode pre = head; int total; for (total = 1; cur.next != null; total++) cur = cur.next; for (int i = 1; i < total - k % total; i++) { pre = pre.next; } cur.next = preHead.next; preHead.next = pre.next; pre.next = null; return preHead.next; } }
public class Solution {
/*
* 思路:
* 分析可看出,要得到结果,其实就是修改几个节点间链接关系,具体包括以下三点:
* 1.末尾节点指向头结点,2.倒数第n个元素为头结点,3.倒数第n+1个元素指向null
*/
public ListNode rotateRight(ListNode head, int n) {
if(head==null) return null; //若链表为空,则直接返回null
if(n==0) return head; //若 n 为0,则直接返回链表本身
int count = 1; //用来计数:传入的链表的节点个数
ListNode p = head;
while(p.next!=null) { //直到 p 找到链表末尾节点,停止循环
p = p.next;
count++;
}
p.next = head; //末尾节点指向头结点,整个链表成为一个环
if(n>count) n=n%count;
for(int i=0; i<count-n; i++) { //通过循环让p指向倒数第n+1个元素
p = p.next;
}
head = p.next; //倒数第n个元素为头结点
p.next = null; //倒数第n+1个元素为末尾节点,指向null
return head;
}
}
题目:输入k和链表的头结点,循环右移链表的后K个结点。
For example:
Given1->2->3->4->5->NULLand
k
=2,
return4->5->1->2->3->NULL.
思路:
1.首先要找链表的倒数第K个结点;
2.因循环右移的K个结点仍是按原来顺序排列,可考虑用一个先进先出的容器 即队列 将 后K个结点
存储,依次连接在链表首处;
3.但此解法空间复杂度为O(k);
4.将链表首尾相接成环,然后在第K个结点前的结点处断开即可;
因leetcode上测试用例中的k有大于length of list 的情况,故要先遍历一遍然后使k=k%(length of list),
时间复杂度仍为O(n).
代码如下:
public class Solution {
public ListNode rotateRight(ListNode head, int n) {
if(head==null||head.next==null)
return head;
//测试用例中有n大于length of list的情况;
ListNode temp=head;
int count =1;
while(temp.next!=null)
{
temp=temp.next;
count++;
}
n=n%count;
if(0 == n)
return head;
ListNode first=head;
ListNode second=head;
//先找到倒数第n个结点;
int num=1;
while(num<n&&second!=null)
{
second=second.next;
num++;//while循环中一定要注意别少了对变量的修改,避免进入死循环;
}
//firstpre记录倒数第n个结点的上一个结点;
ListNode firstpre=first;
while(second.next!=null)
{
firstpre=first;
first=first.next;
second=second.next;
}
second.next=head;
head=first;
firstpre.next=null;
return head;
}
}
/*
* 目的:滚动链表
* 方法:
* 1.求链表长度,同时记下尾结点
* 2.计算滚动次数k=k%len
* 3.将链表在len-k除截断,然后将后面一部分接到前面
*/
ListNode *rotateRight(ListNode *head, int k) {
if (head==nullptr||head->next == nullptr||k<=0){
return head;
}
int len = 0;
ListNode*p = head,*tail=nullptr;
while(p){
if (p->next == nullptr)
tail = p;
p=p->next;
len++;
}
k = k%len;
ListNode dummy(-1);
dummy.next = head;
ListNode*pre = &dummy;
for (int i = 0; i < (len-k);++i){
pre = pre->next;
}
tail->next = dummy.next;
dummy.next = pre->next;
pre->next = nullptr;
return dummy.next;
}
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *rotateRight(ListNode *head, int k) {
if(!head || k==0 || !head->next) return head;
//ListNode *root = new ListNode(-99999);
//root->next = head;
ListNode *cur = head;
int n = 1;
//得到链表长度
while(cur->next){
cur = cur->next;
n += 1;
}
//首尾相连
cur->next = head;
int left = n-k % n;
//继续跑n-k步
while(left--){
cur = cur->next;
}
head = cur->next;
cur->next = NULL;
return head;
}
};
public class Solution {
public ListNode rotateRight(ListNode head, int n) {
if(head == null || head.next == null || n == 0) {
return head;
}
ListNode cur = head;
int index = 0;
int length = 0;
//链表长度
while(cur != null) {
cur = cur.next;
length++;
}
cur = head;
//倒数第n个节点,正数是第 length-n 个节点
//题意里会循环查找,n可能比链表长,需要取模运算,找到断开的节点
while(++index != length-n%length) {
cur = cur.next;
}
//当前节点是尾节点,说明倒数节点为头结点,无需翻转,直接返回
if(cur.next == null) {
return head;
}
//断开处的节点
ListNode newHead = cur.next;
cur.next = null;
cur = newHead;
//遍历到尾部
while(cur.next != null) {
cur = cur.next;
}
//两段链表相连
cur.next = head;
return newHead;
}
}
class Solution {
public:
ListNode *rotateRight(ListNode *head, int k)
{
if(head==nullptr || k<=0)
return head;
ListNode *p=head;
int len = 0;
while(p)
{
++len;
p = p->next;
}
k = k%len;
if(k==0) return head;
ListNode *fast = head,*slow = head;
for(int i=0;i<k;i++)
fast = fast->next;
while(fast->next)
{
slow = slow->next;
fast = fast->next;
}
ListNode *newHead = slow->next;
slow->next = nullptr;
fast->next = head;
return newHead;
}
};
简直在试答案嘛!测试用例有超过链表长度情况,所以要首先求链表长度len,然后n对len求余
就是找到倒数第k个结点,改变指针就可以了
public class Solution {
public ListNode rotateRight(ListNode head, int n) {
if(head == null || head.next == null)
return head;
ListNode tmp = head;
int len = 0;
while(tmp != null){
len++;
tmp = tmp.next;
}
n = n % len;
if(n == 0)
return head;
ListNode cur = head;
ListNode fast = head;
ListNode slow = head;
for(int i = 0; i < n; i++){
if(fast != null)
fast = fast.next;
else
return null;
}
// 这是当n==len的情况
if(fast == null)
return head;
// 找到倒数第k个结点的前一个结点slow
while(fast.next != null){
fast = fast.next;
slow = slow.next;
}
// slow的next是新的head
ListNode newhead = slow.next;
slow.next = null;
fast.next = cur;
return newhead;
}
}
class Solution {
public:
ListNode *rotateRight(ListNode *head, int k) {
if(head == NULL || head->next == NULL || k <= 0) return head;
ListNode* pNode = head;
int len = 0;
ListNode* tail;
while(pNode != NULL) {
len++;
if(pNode->next == NULL) tail = pNode;
pNode = pNode->next;
}
tail->next = head;
pNode = tail;
int idx = len - (k % len);
while(idx > 0) {
idx--;
pNode = pNode->next;
}
ListNode* phead = pNode->next;
pNode->next = NULL;
return phead;
}
};
class Solution {
public:
ListNode *rotateRight(ListNode *head, int k) {
int length = 0;
ListNode *p = head;
ListNode *last = NULL;
while(p)
{
length ++;
last = p;
p = p->next;
}
if(length == 0 || k==0) return head;
k= k%length;
ListNode *newhead = head;
last->next = head;
for(int i=k;i<length;i++){
p = newhead;
newhead = newhead->next;
}
p->next = NULL;
return newhead;
}
};
public class Solution {
public ListNode rotateRight(ListNode head, int k) {
if(head==null||k==0)
return head;
int len = 0;
ListNode cur = head;
ListNode last = null;
while(cur!=null){
len++;
last = cur;
cur = cur.next;
}
if(k>=len&&len!=0)
k %= len;
if(k==0)
return head;
last.next = head;//形成环路
cur = head;//因为是右移动,所以从头开始遍历到倒数第k个元素
for(int i = 1;i<=len-k;i++){
last = cur;
cur = cur.next;
}
//cur是头
last.next = null;
return cur;
}
}
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param head ListNode类
* @param k int整型
* @return ListNode类
*/
public ListNode rotateRight (ListNode head, int k) {
// write code here
if(head==null || k==0) return head;
//双指针
ListNode slow = head;
ListNode fast = head;
while(k>0){
if(fast == null) fast=head;
fast =fast.next;
k--;
}
if(fast == null) return head;
while(fast.next!=null){
slow=slow.next;
fast=fast.next;
}
ListNode temp =slow.next;
slow.next=null;
fast.next=head;
return temp;
}
} import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param head ListNode类
* @param k int整型
* @return ListNode类
*/
//注意一个地方,他说的是向右转,那么指针就是向左走
public ListNode rotateRight (ListNode head, int k) {
// write code here
//思路:用头尾指针进行操作
if(head==null)return head;
ListNode tail = head;
int len=1;
while(tail.next!=null){
tail = tail.next;
len++;
}
k = len - k%len;
// for(int i=0;i<k;i++){
// tail.next = head1;
// head1 = head.next;
// tail = tail.next;
// tail.next =null;
// }
tail.next=head;
for(int i=0;i<k ;i++){
tail = tail.next;
}
head = tail.next;
tail.next = null;
return head;
}
} 基本思路:
k = k mod n 代码如下:
//
// Created by jt on 2020/9/26.
//
class Solution {
public:
/**
*
* @param head ListNode类
* @param k int整型
* @return ListNode类
*/
ListNode* rotateRight(ListNode* head, int k) {
// write code here
// 如果只有0个或1个节点
if (!head || k == 0) return head;
// 将k与链表长度取模
int n = 1;
ListNode *p = head, *q = head;
while (p->next) { ++n; p = p->next; }
k %= n; k = n - k;
// 找到新链表头节点的前一个节点
while (--k > 0) { q = q->next; }
// 合链
p->next = head;
// 断链
ListNode *newHead = q->next;
q->next = nullptr;
return newHead;
}
};
class ListNode: def __init__(self, x): self.val = x self.next = None class Link: def __init__(self): self.head = None def addlink(self,val): node1=ListNode(val) if self.head==None: self.head=node1 return else: cur=self.head while(cur.next): cur=cur.next cur.next=node1 return # # # @param head ListNode类 # @param k int整型 # @return ListNode类 # class Solution: def rotateRight(self, head, k): # write code here if head == None&nbs***bsp;k == 0: return head totallist=[] while(head): totallist.append(head.val) head=head.next while(k): totallist.insert(0,totallist.pop()) k-=1 l1=Link() for i in totallist: l1.addlink(i) return l1.head
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
* 思路:将一个链表从待旋转节点分开,如 1 -> 2 -> 3 -> 4 ->5 旋转2次的结果 4 ->5 -> 1 -> 2 -> 3
* 可以看做 4->5 + 1 -> 2 -> 3,即从3的位置分开
* @param head
* @param k
* @return
*/
public ListNode rotateRight(ListNode head, int k) {
// 不旋转
if (head == null || k == 0) {
return head;
}
// 获取链表长度
ListNode cur = head;
int len = 0;
while (cur != null) {
cur = cur.next;
len++;
}
k = k % len;
// 不旋转
if (k == 0) {
return head;
}
// pre为待旋转节点的前一个节点
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode pre = dummy;
int now = 0;
while (pre != null) {
pre = pre.next;
now++;
if (now == len - k) {
break;
}
}
ListNode tempNode = pre.next;
pre.next = null;
// 开始旋转
ListNode secondDummy = new ListNode(0);
secondDummy.next = tempNode;
while (tempNode.next != null) {
tempNode = tempNode.next;
}
tempNode.next = dummy.next;
return secondDummy.next;
}
} public ListNode rotateRight (ListNode head, int k) {
if (head == null || k == 0){
return head;
}
//获取链表长度
ListNode p = head;
int len = 1;
while (p.next != null){
len++;
p = p.next;
}
//计算旋转后的头部位置
k = len - k%len;
//尾部指向头部
p.next = head;
//接着找到旋转k后的头
for (int i = 0; i < k; i++) {
p = p.next;
}
//设置新head,断开环
head = p.next;
p.next = null;
return head;
}