• [面试经典编程题] 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;
        }
    
  • 相关阅读:
    禅道导出用例模板乱码问题
    安装docker,部署禅道
    清理ubuntu apt中不用的源
    golang和python连接阿里云MongoDB云数据库(解决ReplicaSetNoPrimary错误)
    10分钟使用腾讯轻量应用服务器与frp开启内网穿透实现ssh
    java初学笔记
    elasticsearch相关
    XML转化问题,
    借鉴别人的。做个笔记SourceTree 使用介绍
    SQL 查询数据库是否存在该表该字段该内容
  • 原文地址:https://www.cnblogs.com/jiyongjia/p/13296043.html
Copyright © 2020-2023  润新知