• 3-链表篇(3)


    附1:Stack API

    附2:ArrayList API

    题一:输入一个链表,按链表从尾到头的顺序返回一个ArrayList。

    法一:递归

     1 /**
     2 *    public class ListNode {
     3 *        int val;
     4 *        ListNode next = null;
     5 *
     6 *        ListNode(int val) {
     7 *            this.val = val;
     8 *        }
     9 *    }
    10 *
    11 */
    12 import java.util.ArrayList;
    13 public class Solution {
    14     ArrayList list = new ArrayList();
    15     public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
    16         if(listNode!=null){
    17             printListFromTailToHead(listNode.next);
    18             list.add(listNode.val);
    19         }
    20         return list;
    21     }
    22 }

     

    法二:Stack

     1 import java.util.*;
     2 public class Solution {
     3     ArrayList list = new ArrayList();
     4     public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
     5         Stack stack = new Stack();
     6         while(listNode!=null){
     7             stack.push(listNode.val);
     8             listNode = listNode.next;
     9         }
    10         while(!stack.empty()){
    11             list.add(stack.pop());
    12         }
    13         return list;
    14     }
    15 }

     

    法三:ArrayList内部方法

     1 import java.util.ArrayList;
     2 public class Solution {
     3     public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
     4         ArrayList list = new ArrayList();
     5         while(listNode!=null){
     6             list.add(0,listNode.val);//相当于insert,在0位置插入元素
     7             listNode = listNode.next;
     8         }
     9         return list;
    10     }
    11 }

     题二:给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。

    分析:三步走

      1.判断是否有环-》设置两个指针lp、rp,lp一次走一步,rp一次走两步。如果rp能够追上lp则说明有环(rp通过环绕了一圈和lp相遇,否则rp直接走到链表尾部),如果rp走到尾部还没有相遇则说明无环;

      2.得到环中结点的数目-》第一步结束时,lp和rp会在环内相遇,rp此时停止遍历,lp开始一个节点一个节点遍历,再次相遇时(lp在环内走一圈)即可求出环内节点数目(此处可设置整数n++)。

      3.找到环的入口-》通过第二步求出环内节点数n,此时可再设置两个指针,一个指针先走n步(此时指针之间有n-1个节点),两指针同时遍历,相遇时指向的节点即为环的入口。

     1 /*
     2  public class ListNode {
     3     int val;
     4     ListNode next = null;
     5 
     6     ListNode(int val) {
     7         this.val = val;
     8     }
     9 }
    10 */
    11 public class Solution {
    12 
    13     public ListNode EntryNodeOfLoop(ListNode pHead)
    14     {
    15         ListNode lp=pHead;
    16         ListNode rp=pHead;
    17         boolean flag = false;//是否有环标志
    18         //1.判断是否有环
    19         while(rp.next!=null){//rp还没走到末尾
    20             lp=lp.next;
    21             rp=rp.next.next;
    22             if(lp==rp){
    23                 flag=true;
    24                 break;//此时两个指针在环内相遇
    25             }
    26         }
    27         if(!flag){//没环
    28             return null;
    29         }else{
    30             //2.得到环中结点的数目
    31             int n=1;
    32             lp = lp.next;
    33             while(lp!=rp){//while循环完,两指针在相同位置再次相遇
    34                 lp=lp.next;//rp不动,lp一步一步走
    35                 n++;
    36             }
    37             //3.找到环的入口
    38             lp=pHead;
    39             rp=pHead;
    40             for(int i=0;i<n;i++){
    41                 rp=rp.next;//rp先走n步
    42             }
    43             while(lp!=rp){//两指针同时走
    44                 lp=lp.next;
    45                 rp=rp.next;
    46             }
    47             return lp;
    48         }
    49 
    50     }
    51 }

     

     题三:在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5

     分析:

      关键点:链表有序,并且重复的节点不保留,全删除。

      整体思想:遍历链表,通过比较当前节点和前后节点的值,找出满足条件的节点,添加到自设的头节点之后;

      注意:1.自设头节点是为了解决头节点重复问题(自己搞一个头结点,题目中的直接遍历即可)

         2.还要注意末尾重复问题-》实行“断尾”手段----head.next=null;每次添加完满足条件的节点之后,将该节点之后的连接去除(干干净净,只      关注该节点)

     1 /*
     2  public class ListNode {
     3     int val;
     4     ListNode next = null;
     5 
     6     ListNode(int val) {
     7         this.val = val;
     8     }
     9 }
    10 */
    11 public class Solution {
    12     public ListNode deleteDuplication(ListNode pHead)
    13     {
    14          //为了解决头节点重复的问题,重新设置一个头结点
    15         ListNode head = new ListNode(-1);
    16         ListNode tmp=head;//保存返回值
    17         ListNode pre = null;//前一个结点
    18         ListNode cur = pHead;//当前节点
    19         ListNode next = null;//后一个节点
    20         while(cur!=null){
    21             next = cur.next;
    22             if((pre==null||cur.val!=pre.val)&&(next==null||cur.val!=next.val)){//当前节点值和前后节点值都不相同,则将当前节点挂在tmp之后;
    23                 head.next = cur;
    24                 head = head.next;//递进
    25                 head.next=null;//防止链表末尾重复
    26             }
    27             pre = cur;
    28             cur = next;
    29         }
    30         return tmp.next;//返回自设头结点的下一个节点
    31     }
    32 }

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    PipeCAD设备管口方位图
    Status code: 404 for http://mirrors.cloud.aliyuncs.com/centos/8/AppStream/x86_64/os/repodata/repom
    LNMP下Redis介绍以及安装(Linux)
    CentOS Linux 8 AppStream 错误:为仓库 ‘appstream‘ 下载元数据失败 : Cannot prepare internal mirrorlist: No URLs
    EndNote 使用经验(GT/T 77142015格式引文)
    EndNote 使用经验(标题出现 %J .....)
    EndNote 使用经验(移除重复文献)
    EndNote 使用经验(初次使用)
    20192409潘则宇 实验七 网络欺诈与防范
    20192409潘则宇 实验六 Metasploit攻击渗透实践
  • 原文地址:https://www.cnblogs.com/qmillet/p/11951940.html
Copyright © 2020-2023  润新知