60、排列序列
题目
给出集合 [1,2,3,...,n]
,其所有元素共有 n!
种排列。
按大小顺序列出所有排列情况,并一一标记,当 n = 3
时, 所有排列如下:
-
"123"
-
"132"
-
"213"
-
"231"
-
"312"
-
"321"
给定 n
和 k
,返回第 k
个排列。
示例 1:
输入:n = 3, k = 3
输出:"213"
Code
class Solution {
public String getPermutation(int n, int k) {
int[] factorial = new int[n];
factorial[0] = 1;
for (int i = 1; i < n; ++i) {
factorial[i] = factorial[i - 1] * i;
}
--k;
StringBuffer ans = new StringBuffer();
int[] valid = new int[n + 1];
Arrays.fill(valid, 1);
for (int i = 1; i <= n; ++i) {
int order = k / factorial[n - i] + 1;
for (int j = 1; j <= n; ++j) {
order -= valid[j];
if (order == 0) {
ans.append(j);
valid[j] = 0;
break;
}
}
k %= factorial[n - i];
}
return ans.toString();
}
}
61、旋转链表
题目
给你一个链表的头节点 head
,旋转链表,将链表每个节点向右移动 k
个位置。
示例:
输入:head = [1,2,3,4,5], k = 2
输出:[4,5,1,2,3]
解题思路
-
理解问题:题目要求将链表向右旋转k个位置。例如,对于链表[1, 2, 3, 4, 5],k=2,旋转后应得到[4, 5, 1, 2, 3]。
-
特殊情况处理:如果链表为空、只有一个节点或k为0,则无需旋转,直接返回原始头节点。
-
计算链表长度:遍历链表以确定其长度。
-
调整k值:如果k大于链表长度,使用k % 长度来找到实际需要旋转的节点数。
-
找到旋转断开点:遍历链表,找到第(长度 - k)个节点,该节点的下一个节点将是旋转后链表的新头节点。
-
执行旋转:将找到的节点的next设置为null,切断链表。然后将链表的末尾节点连接到原始头节点,形成旋转后的链表。
解题过程
-
初始化:创建一个指针
current
用于遍历链表,两个指针newHead
和tail
分别用于存储新头节点和末尾节点。 -
计算长度:使用
current
遍历链表,计算并存储链表长度。 -
特殊情况:如果链表长度小于等于1或k为0,直接返回原始头节点。
-
调整k:如果k大于链表长度,更新k为k % 长度。
-
找到新头节点:使用两个指针
slow
和fast
,fast
移动速度是slow
的k倍,当fast
到达链表末尾时,slow
所在位置的下一个节点即为新头节点。 -
断开并连接链表:将
slow
的next
设置为null,切断链表。然后将current
(末尾节点)的next
指向原始头节点,完成旋转。
复杂度
-
时间复杂度:O(n),其中n是链表的长度。需要遍历整个链表来确定长度和找到旋转点。
-
空间复杂度:O(1),只需要几个额外的指针变量,不依赖于输入大小。
Code
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode rotateRight(ListNode head, int k) {
if (head == null || head.next == null || k == 0) {
return head;
}
int length = 1;
ListNode current = head;
while (current.next != null) {
current = current.next;
length++;
}
k = k % length;
if (k == 0) {
return head;
}
current = head;
for (int i = 1; i < length - k; i++) {
current = current.next;
}
ListNode newHead = current.next;
current.next = null;
ListNode tail = newHead;
while (tail.next != null) {
tail = tail.next;
}
tail.next = head;
return newHead;
}
}