zoukankan      html  css  js  c++  java
  • 链表基础训练(一)

    题目一:

      删除链表中的重复元素。

      思路:一是利用哈希表(HashSet),哈希表特别适合于判断集合中是否有重复的元素。二是直接使用遍历链表,使用两层for循环去遍历再来找出重复的元素。下面给出第一种方法的代码。

     1 import java.util.HashSet;
     2 
     3 public class 删除重复结点 {
     4     // 创建链表的节点
     5     private static class ListNode {
     6         ListNode next;
     7         Object value;
     8 
     9         public ListNode(Object value){
    10             super();
    11             this.value = value;
    12         }
    13     }
    14 
    15     public static void main(String[] args){
    16         int data[] = {1, 6, 6, 7, 3, 3, 5, 3, 8, 9, 10, 10};  // 输出 1 6 7 3 5 8 9 10 
    17         //哑元 空节点
    18         ListNode head = new ListNode(null);
    19         ListNode p = head;
    20         for(int i = 0; i < data.length; i++){
    21             p.next = new ListNode(data[i]);
    22             //指针往下进行移动
    23             p = p.next;
    24         }
    25         removeReptition(head);
    26         ListNode p1 = head.next;
    27         while(p1 != null){
    28             System.out.print(p1.value + " ");
    29             p1 = p1.next;
    30         }
    31     }
    32 
    33     private static void removeReptition(ListNode head){
    34         ListNode p = head.next;
    35         ListNode pre = head;
    36         HashSet set = new HashSet();
    37         //遍历哈希表
    38         while(p != null){
    39             if(set.contains(p.value)){
    40                 pre.next = p.next;
    41             }else{
    42                 set.add(p.value);
    43                 pre = p;
    44             }
    45             p = p.next;
    46         }
    47     }
    48 }
    View Code

    题目二:

      实现一个算法,输出单向链表中的第k个节点。

      思路: 从题目可以看出,只是给出了链表的头结点,所以我们是不知道链表中含有几个元素,假如知道几个元素的话那就很简单了。由于我们这里只知道头节点,我们可以使用一种叫快行指针(双行指针)的技巧来解决这道题目。

     1 public class 倒数第k个节点 {
     2     // 特别要注意边界的问题
     3     public static ListNode FindKthToTail(ListNode head, int k) {
     4         if (head == null || k <= 0)
     5             return null;
     6         ListNode p1 = head;
     7         ListNode p2 = head;
     8         int count = 0;
     9         while (p2 != null && count < k) {
    10             p2 = p2.next;
    11             count++;
    12         }   // p2 与 p1 相差 k 距离
    13         if (count < k) {
    14             return null;
    15         }
    16         while (p2 != null) {  // 当p2为null时,p1就指向了要删除的那个节点。
    17             p1 = p1.next;
    18             p2 = p2.next;
    19         }
    20         // System.out.println(p1.data);
    21         return p1;
    22     }
    23 
    24     public static void main(String[] args) {
    25         int[] arr = { 1, 2, 3, 4, 5 };
    26         ListNode head = new ListNode(arr[0]);// 哑元
    27         ListNode p = head;
    28         for (int i = 1; i < arr.length; i++) {
    29             p.next = new ListNode(arr[i]);
    30             p = p.next;
    31         }
    32         // System.out.println(head);
    33         ListNode l1 = FindKthToTail(head, 3);
    34         System.out.println("倒数第三个节点:" + l1.val);
    35 
    36     }
    37     // 5,{1,2,3,4,5}
    38 }
    39 class ListNode {
    40     int val;
    41     ListNode next = null;
    42 
    43     ListNode(int val) {
    44         this.val = val;
    45     }
    46 
    47     @Override
    48     public String toString() {
    49         StringBuilder sb = new StringBuilder(val + "");
    50         ListNode nnext = next;
    51         while (nnext != null) {
    52             sb.append(nnext.val);
    53             nnext = nnext.next;
    54         }
    55         return sb.toString();
    56     }
    57 }
    View Code

      结果:

        

    题目三:  

      实现一个算法,删除单向链表中的某个节点,假定你只能访问该节点。输入单向链表a->b->c->d->e中的c,结果不返回任何数据,单链表变为a->b->d->e。给定待删除的节点,请执行删除操作,若该节点为尾节点,返回false,否则返回true。

      思路:题目中限定了只能访问该节点,那么之前的节点我们是不能够访问到的,所以只能访问到节点以及通过next来访问下面的节点。我们可以使用到一种特别的技巧就是复制当前节点的后继节点的内容给当前节点,然后改变当前节点的指向跳过后继直接指向后继的下一个元素。当传入的节点是最后一个节点的时候我们是不能够进行删除的,因为最后一个节点的next为空我们不能够复制内容来进行删除的,所以直接返回false。

     1 public class 删除某节点 {
     2     public static boolean removeNode(ListNode pNode) {
     3         if (pNode.next == null)
     4             return false;
     5         pNode.val = pNode.next.val;// 复制后继的内容
     6         pNode.next = pNode.next.next;// 跨越后继
     7         return true;
     8     }
     9     public static void main(String[] args) {
    10         int[] arr = { 1, 2, 3, 4, 5 };
    11         ListNode head = new ListNode(arr[0]);// 哑元
    12         ListNode p = head;
    13         for (int i = 1; i < arr.length; i++) {
    14             p.next = new ListNode(arr[i]);
    15             p = p.next;
    16         }
    17         ListNode p1 = head.next;
    18         removeNode(p1);
    19         while(head!=null){
    20             System.out.println(head.val);
    21             head = head.next;
    22         }
    23     }
    24 }
    25 class ListNode {
    26     int val;
    27     ListNode next = null;
    28 
    29     ListNode(int val) {
    30         this.val = val;
    31     }
    32 
    33     @Override
    34     public String toString() {
    35         StringBuilder sb = new StringBuilder(val + "");
    36         ListNode nnext = next;
    37         while (nnext != null) {
    38             sb.append(nnext.val);
    39             nnext = nnext.next;
    40         }
    41         return sb.toString();
    42     }
    43 }
    View Code

      结果:

        

      可以简单的总结一下,我们可以发现这里对链表进行操作的时候并没有使用到多复杂的函数,只是定义了一个简单的ListNode类而已,像前面实现的增删查改等操作这些题目根本就没有用,事实上也用不上。所以可以发现对链表的考察呢就是利用它的前驱或者后继节点,然后我们可以推断后面其他的数据结构的考察方式可能和链表一样,只是利用基本的东西,对实现的那些函数根本用不上。



  • 相关阅读:
    2019中山纪念中学夏令营-Day19 数论初步【GCD(最大公约数),素数相关】
    2019中山纪念中学夏令营-Day14 图论初步【dijkstra算法求最短路】
    2019中山纪念中学夏令营-Day12[JZOJ]
    2019中山纪念中学夏令营-Day9[JZOJ](第六次模拟赛)
    2019中山纪念中学夏令营-Day4[JZOJ]
    2019中山纪念中学夏令营-Day2[JZOJ]
    2019中山纪念中学夏令营-Day1[JZOJ]
    CCPC2019江西省赛-Problem G.Traffic
    T137223 节能主义
    T137226 彩虹海
  • 原文地址:https://www.cnblogs.com/xiaoyh/p/10386288.html
Copyright © 2011-2022 走看看