zoukankan      html  css  js  c++  java
  • [面试经典编程题] 2 翻转单链表的四种方法

    翻转单链表

    题目描述

    image-20200713211916471

    思路

    三个指针,分别n1,n2,n3;三个指针不断往后移动。

    image-20200713204850871

    Java代码

    方法1:三个指针标记循环往后走

     //方法3:三个指针循环后移
        public ListNode reverseList(ListNode head) {
            if(head==null) {return null;}
    
            ListNode n0 = null;
            ListNode n1 = head;
            ListNode n2 = n1.next;
            while(n1!=null){
                //翻转
                n1.next = n0;
    
                //三个指针移动
                n0 = n1;
                n1 = n2;
                //在结尾的地方,这里存在为空的情况,需判断
                if(n2!=null){
                    n2 = n2.next;
                }
            }
            return n0;//最终结束是返回n1
        }
    

    输出最优:

    image-20200713212241591

    方法2:头插法

    思路:

    image-20200713213910782

    Java代码:

    //方法4:头插法
         public ListNode reverseList(ListNode head) {
             ListNode newHead = null;
             ListNode cur = head;
             while(cur!=null){
                //保存下一个
                ListNode next = cur.next;
                //摘一个下来
                cur.next = newHead;
                newHead = cur;
                //然后取下一个
                cur = next;
             }
             //退出while就是取完了
             return newHead;
         }
    

    效率:

    image-20200713214029349

    方法3:借助栈

     //方法1:借助栈完成反转
        public ListNode reverseList1(ListNode head) {
            //借助栈
            Deque<ListNode> stack = new LinkedList();
            ListNode newHead=null;  //返回的逆转栈
    
            //安全验证
            if(head==null) return null;
            if(head.next==null) return head;
    
            //一个个入栈
            while(head!=null){
                stack.push(head);
                head = head.next;
            }
            
            head = stack.pop();
            ListNode cur = head;
            //出栈
            while(!stack.isEmpty()){
                ListNode node = stack.pop();
    
                /*  //探究:验证节点指向的测试代码
                System.out.println("node:"+node+"--->>node.Next:"+node.next);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }*/
                
                //我们虽然正向存入了栈中,但是每个节点的next的指向还没变,在这里要消除
                node.next=null;  //这一步关键(//消除正向原本的指向关系)
                cur.next = node;
                cur = node;
            }
    
            return head;
        }
    

    方法4:简单递归

    //方法2:简单递归
        public ListNode reverseList2(ListNode head) {
            if(head==null) {return null;}
            if (head.next==null) {return head;}
            
            //1 前向遍历得到最后的那个节点,并标记
            ListNode rev = head;
            while (rev.next!=null){
                rev = rev.next;  //即rev标记了最后的节点
            }
            
            //2 我们再次前向遍历,改变指针指向顺序
            ListNode cur=head;
            while (cur.next!=null){
                cur.next.next=cur;
                cur.next=null;
                //节点后移
                cur=cur.next;
            }
            
            //返回最后的那个节点做头节点
            return rev;
        }
    
  • 相关阅读:
    js中null " "的区别
    简略的地图API应用
    JSON的一个例子(代码来源于网上)
    浅谈Event Flow、Process、Method及其Applications
    JS中object与constructor的分析
    浅谈for...in与for....of
    浅谈语言的过去与未来
    正则表达式的四个小应用
    BOM详细
    BOM
  • 原文地址:https://www.cnblogs.com/jiyongjia/p/13296043.html
Copyright © 2011-2022 走看看