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 }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2019-12-06 14:04  Qmillet  阅读(326)  评论(0编辑  收藏  举报