【LeetCode题解】61_旋转链表(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
解法:双指针
思路
求解这道题等价于找到链表倒数第 k 个节点,然后将之前的所有节点放到链表的尾部,形成一个新的链表,相当于 LeetCode 第 19 题的进阶版。
对于寻找单向链表的倒数第 \(k\) 个元素问题,可以采用双指针的方法进行求解。
- 令指针
p1
和指针p2
均指向表头,然后让指针p2
跳转 \(k - 1\) 次,此时指针p2
处于链表的第 \(k\) 个节点
- 接着,让两个指针同时向链表尾部跳转,直到指针
p2
处于链表的尾部,此时,指针p1
指向的节点正是链表的倒数第 \(k\) 个节点
在找到倒数第 \(k\) 个节点后,只需要将指针 p2
指向链表头 head
、指针 p1
的前一个节点的 next
指针指向 null
,最后指针 p1
就是新的链表的表头。
值得注意的是,在这道题中,我们需要找到的是链表的倒数第 \(k+1\) 个节点,从而才能对该节点的 next
指针进行操作(指向 null
)。同样地,也需要注意一些边界情况,比如表头 head
为空,k
大于链表长度等。
Java 实现
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode rotateRight(ListNode head, int k) {
// 边界情况处理
if (head == null) {
return head;
}
// 统计链表长度并对k进行取余操作
int length = 1;
ListNode tmp = head;
while (tmp.next != null) {
tmp = tmp.next;
++length;
}
k = k % length;
if (k == 0) {
return head;
}
// 寻找倒数第k+1个节点
ListNode p1 = head, p2 = head;
for (int i = 0; i < k; ++i) {
p2 = p2.next;
}
while (p2.next != null) {
p1 = p1.next;
p2 = p2.next;
}
// 旋转链表
ListNode newHead = p1.next;
p1.next = null;
p2.next = head;
return newHead;
}
}
// Runtime: 6 ms
// Your runtime beats 100.00 % of java submissions.
Python 实现
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def rotateRight(self, head, k):
"""
:type head: ListNode
:type k: int
:rtype: ListNode
"""
# 边界情况处理
if not head:
return head
# 统计链表的长度并对k进行取余操作
tmp, n = head, 1
while tmp.next:
tmp, n = tmp.next, n + 1
k = k % n
if k == 0:
return head
# 找到倒数第k+1个节点
p1, p2 = head, head
for i in range(k):
p2 = p2.next
while p2.next:
p1 = p1.next
p2 = p2.next
# 旋转链表
new_head = p1.next
p1.next, p2.next = None, head
return new_head
# Runtime: 44 ms
# Your runtime beats 99.11 % of python3 submissions.
复杂度分析
- 时间复杂度:\(O(n)\),其中 \(n\) 表示链表的长度。首先需要迭代 \(n\) 次找出链表的长度,接着让指针
p2
迭代 \(k\) 次到达第 \(k+1\) 个节点的位置,最后还需要迭代 \(n-(k+1)\) 次使得两个指针一个指向链表尾部,一个指向倒数第 \(k+1\) 个节点,而迭代所执行的操作的时间复杂度都是 \(O(1)\) 的,所以最后总的时间复杂度是 \(O(n)\) 的 - 空间复杂度:\(O(1)\)
【LeetCode题解】61_旋转链表(Rotate-List)的更多相关文章
- LeetCode 61:旋转链表 Rotate List
给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数. Given a linked list, rotate the list to the right by k pla ...
- [Swift]LeetCode61. 旋转链表 | Rotate List
Given a linked list, rotate the list to the right by k places, where k is non-negative. Example 1: I ...
- LeetCode - 61、旋转链表
给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数. 示例 1: 输入: 1->2->3->4->5->NULL, k = 2 输出: 4-& ...
- LeetCode题:旋转链表
原题: 给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数. 示例 1: 输入: 1->2->3->4->5->NULL, k = 2输出: ...
- 【LeetCode】61. 旋转链表
61. 旋转链表 知识点:链表: 题目描述 给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置. 示例 输入:head = [1,2,3,4,5], k = 2 输出:[4 ...
- leetCode题解之旋转数字
1.题目描述 X is a good number if after rotating each digit individually by 180 degrees, we get a valid n ...
- LeetCode题解-147 对链表进行插入排序
对链表进行插入排序. 插入排序的动画演示如上.从第一个元素开始,该链表可以被认为已经部分排序(用黑色表示). 每次迭代时,从输入数据中移除一个元素(用红色表示),并原地将其插入到已排好序的链表中. 插 ...
- LeetCode题解-147 对链表进行插入排序 Medium
对链表进行插入排序. 插入排序的动画演示如上.从第一个元素开始,该链表可以被认为已经部分排序(用黑色表示). 每次迭代时,从输入数据中移除一个元素(用红色表示),并原地将其插入到已排好序的链表中. 插 ...
- LeetCode 189:旋转数组 Rotate Array
公众号:爱写bug(ID:icodebugs) 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数. Given an array, rotate the array to the ...
随机推荐
- hdu 1.2.3
很简单的算法基础题...闰年判断以及计算 #include<iostream> #include<cstdio> using namespace std; int main() ...
- Shell 命令实现词频统计
杨贵福老师的方法 cat tr sed sort head 命令的综合使用方式1 $ cat pg11.txt |tr -cs A-Za-z\' '\n' |sed "/'/d"| ...
- 一个简单的用python 实现系统登录的http接口服务实例
用python 开发一个登录的http接口: 用户登录数据存在缓存redis里,登录时根据session判断用户是否已登录,session有效,则直接返回用户已登录,否则进mysql查询用户名及密码, ...
- OpencvSharp 在WPF的Image控件中显示图像
1.安装OpencvSharp 我使用的是VS2013 社区版,安装OpencvSharp3.0 在线安装方法:进入Tools,打开NuGet的包管理器 搜索Opencv 安装之后就可以使用,无需再做 ...
- Windows核心编程:第11章 Windows线程池
Github https://github.com/gongluck/Windows-Core-Program.git //第11章 Windows线程池.cpp: 定义应用程序的入口点. // #i ...
- Flask系列08--Flask中flask_session, redis插件
一.安装 1.flask_session 不想将Session的信息存放在Cookie 将Session存放在Redis Cookie中保存Session的ID flask中的session是直接将数 ...
- python项目实现配置统一管理的方法
一个比较大的项目总是会涉及到很多的参数,最好的方法就是在一个地方统一管理这些参数.最近看了不少的python项目,总结了两种很有意思的配置管理方法. 第一种 基于easydict实现的配置管理 首先需 ...
- Windows Phone开发手记-WinRT下自定义圆形ItemsControl
这里的ItemsControl指的是Xaml里的集合控件,包括ListView,GridView等,此篇博客主要参考MSDN Blog的一篇文章,具体出处为:http://blogs.msdn.com ...
- Python小白学习之路(二十三)—【生成器补充】
生成器的一些补充 接着下鸡蛋和吃包子! 补充一:生成器只能遍历一次 (总是把生成器比喻成母鸡下鸡蛋,需要一个下一个,首先是下出来的鸡蛋不能塞回母鸡肚子里,其次是一个母鸡一生只能下一定数量的鸡蛋,下完了 ...
- WebForm - 文本框回车事件
document.getElementById("Pwd").onkeyup = function (e) { ) { fun_Login(); } };