• leetcodetop100(29) K 个一组翻转链表


    K 个一组翻转链表
    给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。
    k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
    你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

    方法一:将链表先变成List数组,List数组按K大小分成n块(有余数就为第n+1块),每块翻转(第n+1块不翻转),然后组成一个新的List数组,在按照新的list数组拼接成新的链表返回

    时间复杂度O(n) 空间复杂度O(n) (比较好理解的做出来)

    1. package TOP21_30;
    2. import Util.ListNode;
    3. import java.util.ArrayList;
    4. import java.util.List;
    5. //K 个一组翻转链表
    6. //给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。
    7. //k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
    8. //你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
    9. public class Top29 {
    10. public static ListNode reverseKGroup(ListNode head, int k) {
    11. if (head == null || k == 1) {
    12. return head;
    13. }
    14. List list = new ArrayList<>();
    15. List resutlist = new ArrayList<>();
    16. while (head != null) {
    17. list.add(head.val);
    18. head = head.next;
    19. }
    20. int length = list.size();
    21. // 因为k<=length
    22. int n = length / k;
    23. int t = length % k;
    24. for (int i = 0; i < n; i++) {
    25. List tempList = new ArrayList<>();
    26. for (int j = 0; j < k; j++) {
    27. tempList.add(list.get(i * k + j));
    28. }
    29. resutlist.addAll(reverseList(tempList));
    30. }
    31. if (t != 0) {
    32. List tempList = new ArrayList<>();
    33. for (int i = n * k; i <= length - 1; i++) {
    34. tempList.add(list.get(i));
    35. }
    36. resutlist.addAll(tempList);
    37. }
    38. ListNode node = setNodes(0, resutlist);
    39. return node;
    40. }
    41. public static ListNode setNodes(int index, List nums) {
    42. ListNode res = new ListNode();
    43. res.val = nums.get(index);
    44. if (index == nums.size() - 1) {
    45. res.next = null;
    46. return res;
    47. } else {
    48. res.next = setNodes(index + 1, nums);
    49. }
    50. return res;
    51. }
    52. private static List reverseList(List reverseData) {
    53. List arrayList = new ArrayList<>();
    54. for (int i = reverseData.size() - 1; i >=0; i--) {
    55. arrayList.add(reverseData.get(i));
    56. }
    57. return arrayList;
    58. }
    59. public static void main(String[] args) {
    60. int[] nums = {1,2,3,4,5,6,7,8,9,0};
    61. ListNode node = ListNode.setNodes(0,nums);
    62. ListNode node2 =reverseKGroup(node,3);
    63. ListNode.printListData(node2);
    64. }
    65. }

    方法二:递归 Java

    解题思路
    大致过程可以分解为 1、找到待翻转的k个节点(注意:若剩余数量小于 k 的话,则不需要反转,因此直接返回待翻转部分的头结点即可)。 2、对其进行翻转。并返回翻转后的头结点(注意:翻转为左闭又开区间,所以本轮操作的尾结点其实就是下一轮操作的头结点)。 3、对下一轮 k 个节点也进行翻转操作。 4、将上一轮翻转后的尾结点指向下一轮翻转后的头节点,即将每一轮翻转的k的节点连接起来。

    具体过程看下图。

    1. //递归方法
    2. public static ListNode reverseKGroup2(ListNode head, int k) {
    3. //退出递归的条件
    4. if(head == null ) return head;
    5. ListNode tail = head;
    6. for(int i =0;i
    7. // if(tail == null) break; // 这个是不足k也反转
    8. if(tail == null) return head; // 不足k的节点,保持原来顺序
    9. tail = tail.next;
    10. }
    11. //反转前k个节点
    12. ListNode newHead = reverse(head, tail);
    13. //下一轮的开始还是tail节点,因为你是要确定下一次返回链表的头节点的位置
    14. head.next = reverseKGroup(tail,k);
    15. return newHead;
    16. }
    17. public static ListNode reverse(ListNode head, ListNode tail){
    18. ListNode prev =null;
    19. ListNode cur = head;
    20. //只需要把原来判断尾节点为空的,改为在传入节点就行。
    21. while(cur !=tail){
    22. ListNode next = cur.next;
    23. cur.next = prev;
    24. prev =cur;
    25. cur = next;
    26. }
    27. return prev;
    28. }

    完整可执行代码

    harryptter / LeetcodeTop100 · GitCode

  • 相关阅读:
    【云原生】Helm 架构和基础语法详解
    18.Pandas的数据转换函数map、apply、applymap
    Laravel 博客开发|管理后台里程碑管理
    手机照片回收站无法恢复图片怎么办?2个措施,找回丢失的相册
    ISO三体系的流程及必要性
    python django初步搭建(一)
    Debian12安装.NET7 SDK
    红队专题-从零开始VC++C/S远程控制软件RAT-MFC-屏幕监控
    【信息系统项目管理师】第四章 复盘整体管理知识架构
    基于PHP的化妆品销售网站,MySQL数据库,PHPstudy,前台用户+后台管理,完美运行,有一万多字论文
  • 原文地址:https://blog.csdn.net/harryptter/article/details/133278367