zoukankan      html  css  js  c++  java
  • 25.K个一组翻转链表

    image-20200516162313970

    集合

    思路

    • 存入集合

    • 在集合中进行翻转

    • 遍历操作后的集合 ,构建新的链表

    • 很明显 过程耗时间空间

    代码

    /**
         *6ms  7%
         */
        public ListNode reverseKGroup(ListNode head, int k) {
            if(head==null) return null;
            //存入集合
            List<ListNode> nodes=new ArrayList<>();
            while(true){
                if(head==null){
                    break;
                }
                nodes.add(head);
                head=head.next;
            }
    //        System.out.println(nodes.toString());
            int len=nodes.size();
            int mode=len%k;
            for(int i=0;i<len-mode;i+=k){
                //首尾交换规律
                int index=i+(i+k-1);
                for(int j=i;j<i+k/2;j++){
                    ListNode temp=nodes.get(j);
                    nodes.set(j,nodes.get(index-j));
                    nodes.set(index-j,temp);
                }
            }
            ListNode head2=new ListNode(-1);
            ListNode temp=head2;
            nodes.get(len-1).next=null;//若设置末尾为null 例如[1,2] 翻转后[2,1] 但此时1.next.val=2,构成死循环
            for(ListNode node:nodes){
                temp.next=node;
                temp=temp.next;
            }
    //        list(head2.next);
            return head2.next;
    
        }
    

    • 使用 进行链表交换

      image-20200516171132576

      代码

          /**
           * 使用栈进行交换
           * 3ms  12%
           */
          public ListNode reverseKGroup2(ListNode head, int k) {
              Stack<ListNode> stack=new Stack<>();
              ListNode dummy=new ListNode(-1);
              ListNode p=dummy;
              while(true){
                  int count=0;
                  ListNode tmp=head;
                  while(tmp!=null&&count<k){
                      stack.add(tmp);
                      tmp=tmp.next;
                      count++;
                  }
                  if(count!=k){
                      p.next=head;
                      break;
                  }
                  while(!stack.isEmpty()){
                      p.next=stack.pop();
                      p=p.next;
                  }
                  p.next=tmp;
                  head=tmp;
              }
              return dummy.next;
          }
      
      

    头插法

    参考原文王小二:图解k个一组翻转链表



    图解如下:

    代码

       /**
         * 0ms
         */
        public ListNode reverseKGroup3(ListNode head,int k){
            ListNode dummy=new ListNode(-1);
            dummy.next=head;
    
            ListNode pre=dummy;
            ListNode end=dummy;
            while(end.next!=null){
                for(int i=0;i<k&&end!=null;i++) end=end.next;
                if(end==null) break;
                ListNode start=pre.next;
                ListNode next=end.next;
                end.next=null;
                pre.next=reverse(start);
                start.next=next;
                pre=start;
                end=pre;
            }
            return dummy.next;
        }
        public ListNode reverse(ListNode head){
            ListNode pre=null;
            ListNode cur=head;
            while(cur!=null){
                ListNode next=cur.next;
                cur.next=pre;
                pre=cur;
                cur=next;
            }
            return pre;
        }
    

    问题

    ​ 链表操作(交换)与数组操作 有很大区别 ,数组交换主要是值的交换,而链表是整体。同时需妥善处理next指针,稍不注意易造成节点死循环。 例如[1,2] 翻转后[2,1] 若1.next不设置成null,此时1.next.val=2,构成死循环。

  • 相关阅读:
    Java 技术笔记
    idea启动TOMCAT html 乱码
    IntelliJ IDEA 导入新项目
    InterlliJ Debug方式启动:method breakpoints may dramatically show down debugging
    intelliJ idea #region 代码折叠
    Console 程序在任务计划程序无法读写文件
    Java 发送邮件
    MySQL 索引
    MySQL 临时表
    11 帧差法获取运动
  • 原文地址:https://www.cnblogs.com/yh-simon/p/12901374.html
Copyright © 2011-2022 走看看