题目描述(中等难度)

61. Rotate List - 图1

将最后一个链表节点移到最前边,然后重复这个过程 k 次。

解法一

很明显我们不需要真的一个一个移,如果链表长度是 len, n = k % len,我们只需要将末尾 n 个链表节点整体移动到最前边就可以了。可以结合下边的图看一下,我们只需要找到倒数 n + 1 个节点的指针把它指向 null,以及末尾的指针指向头结点就可以了。找倒数 n 个结点,让我想到了 19题,利用快慢指针。

61. Rotate List - 图2

  1. public ListNode rotateRight(ListNode head, int k) {
  2. if (head == null || k == 0) {
  3. return head;
  4. }
  5. int len = 0;
  6. ListNode h = head;
  7. ListNode tail = null;
  8. //求出链表长度,保存尾指针
  9. while (h != null) {
  10. h = h.next;
  11. len++;
  12. if (h != null) {
  13. tail = h;
  14. }
  15. }
  16. //求出需要整体移动多少个节点
  17. int n = k % len;
  18. if (n == 0) {
  19. return head;
  20. }
  21. //利用快慢指针找出倒数 n + 1 个节点的指针,用 slow 保存
  22. ListNode fast = head;
  23. while (n >= 0) {
  24. fast = fast.next;
  25. n--;
  26. }
  27. ListNode slow = head;
  28. while (fast != null) {
  29. slow = slow.next;
  30. fast = fast.next;
  31. }
  32. //尾指针指向头结点
  33. tail.next = head;
  34. //头指针更新为倒数第 n 个节点
  35. head = slow.next;
  36. //尾指针置为 null
  37. slow.next = null;
  38. return head;
  39. }

时间复杂度:O ( n ) 。

空间复杂度:O(1)。

这里我们用到的快慢指针其实没有必要,快慢指针的一个优点是,不需要知道链表长度就可以找到倒数第 n 个节点。而这个算法中,我们在之前已经求出了 len ,所以我们其实可以直接找倒数第 n + 1 个节点。

  1. ListNode slow = head;
  2. for (int i = 1; i < len - n; i++) {
  3. slow = slow.next;
  4. }

这道题也没有什么技巧,只要对链表很熟,把题理解了,很快就解出来了。

windliang wechat

添加好友一起进步~

如果觉得有帮助的话,可以点击 这里 给一个 star 哦 ^^

如果想系统的学习数据结构和算法,强烈推荐一个我之前学过的课程,可以点击 这里 查看详情