力扣题目
解题思路
java代码
力扣题目:
给你一个链表的头节点 head
,旋转链表,将链表每个节点向右移动 k
个位置。
示例 1:
输入:head = [1,2,3,4,5], k = 2 输出:[4,5,1,2,3]
示例 2:
输入:head = [0,1,2], k = 4 输出:[2,0,1]
解题思路:
算法原理:
首先计算链表的长度,然后对旋转次数 k
取模得到实际需要旋转的次数。通过遍历链表找到新的尾节点和新的头节点,将链表截断并重新连接,实现链表的右旋转。
思路:
- 处理特殊情况,如果链表为空或只有一个节点,直接返回原链表。
- 计算链表长度,并对
k
进行取模,以避免不必要的多次旋转。 - 从链表头开始遍历,找到新的尾节点(位于
len - k - 1
位置)。 - 确定新的头节点,并将原尾节点指向原头节点,完成链表的旋转。
代码分析:
rotateRight
方法中,首先处理特殊情况。- 然后通过一个循环计算链表长度,并更新
k
。 - 再次遍历链表找到新的尾节点。
- 确定新的头节点,截断链表并重新连接。
时间复杂度:O(n),其中 n
是链表的节点数。需要遍历链表两次,一次计算长度,一次找到新的尾节点。
空间复杂度:O(1),只使用了固定的几个变量,空间开销恒定。
java代码:
package org.example;
public class Leetcode61 {
public static void main(String[] args) {
Leetcode61 leetcode61 = new Leetcode61();
leetcode61.rotateRight(new ListNode(1, new ListNode(2)), 2);
// 循环打印链表
ListNode cur = leetcode61.rotateRight(new ListNode(1, new ListNode(2, new ListNode(3, new ListNode(4, new ListNode(5))))), 2);
while (cur != null) {
System.out.println(cur.val);
cur = cur.next;
}
System.out.println(leetcode61.rotateRight(new ListNode(1, new ListNode(2, new ListNode(3, new ListNode(4, new ListNode(5))))), 2));
}
public ListNode rotateRight(ListNode head, int k) {
if (head == null || head.next == null) return head;
int len = 0;
ListNode cur = head;
while (cur != null) {
len++;
cur = cur.next;
}
k %= len;
if (k == 0) return head;
cur = head;
for (int i = 0; i < len - k - 1; i++) cur = cur.next;
ListNode newHead = cur.next;
cur.next = null;
cur = newHead;
while (cur.next != null) cur = cur.next;
cur.next = head;
return newHead;
}
}
更多详细内容同步到公众号,感谢大家的支持!
每天都会给刷算法的小伙伴推送明日一题,并且没有任何收费项