zoukankan      html  css  js  c++  java
  • 第二阶段-day03_Linked

    今天我们主要讲了一些链表的练习题,希望大家可以从中体会链表的使用方式,加深对链表的理解。

    回顾昨天内容:

    总结:
    List
        List subList(int fromIndex, int toIndex) 视图技术
        ListIterator listIterator()
        ListIterator listIterator(int index)
    
    ListIterator
        概述:列表特有的迭代器
        API:
            boolean hasNext()
            boolean hasPrevious()
            E next()
            E previous()
            
            int previousIndex()
            int nextIndex()
            
            void add(E e)
            void remove()
            void set(E e)
    
    数组
        Q1
        Q2
        Q3
        数组的基本操作 总结:增删慢,查找快
    
    链表
        概述:
        分类:
            单链表
            双向链表
            循环链表
            双向循环链表
        单链表的操作
        双向链表的操作
        
        例子:
            a. LRU算法
            b. 求单表的中间元素
            c. 判断单链表是否有环

    3个练习:

     1 package com.cskaoyan.exercise;
     2 
     3 public class Node {
     4     int value;
     5     Node next;
     6 
     7     public Node(int value) {
     8         this.value = value;
     9     }
    10 
    11     public Node(int value, Node next) {
    12         this.value = value;
    13         this.next = next;
    14     }
    15 
    16     @Override
    17     public String toString() {
    18         return "Node{" +
    19                 "value=" + value +
    20                 '}';
    21     }
    22 }

    Ex2:

    方法1. 给一个阈值(10ms),如果在遍历链表的过程中10ms还没有结束,就认为有环。
       2. 迷雾森林

     1 package com.cskaoyan.exercise;
     2 
     3 import java.util.ArrayList;
     4 import java.util.Collection;
     5 import java.util.HashSet;
     6 
     7 /*
     8 判断链表中是否有环
     9 1. 给一个阈值(10ms),如果在遍历链表的过程中10ms还没有结束,就认为有环。
    10 2. 迷雾森林
    11    Collection visited = new ArrayList();
    12    a.遍历链表,获取每一个结点。
    13      判断结点是否在visited集合中存在。
    14      存在:返回true
    15      不存在:将该结点添加到visited中,然后遍历下一个结点
    16    b.遍历结束后,返回false
    17 3. 跑道(快慢指针)
    18     a.创建了快指针和慢指针,快指针每次走两步,慢指针每次走一步
    19     b.遍历链表
    20       如果快指针到到终点:返回false
    21       如果快指针和慢指针相遇:返回true
    22       快指针移动两步
    23       慢指针移动一步
    24  */
    25 public class Ex1 {
    26     /*
    27     时间复杂度:O(n^2) --> O(n)
    28     空间复杂度:O(n)
    29      */
    30     /*public static boolean hasCircle(Node head) {
    31         // Collection visited = new ArrayList();
    32         Collection visited = new HashSet();
    33         Node x = head;
    34         while (x != null) {
    35             if (visited.contains(x)) return true;
    36             visited.add(x);
    37             x = x.next;
    38         }
    39         // 遍历结束
    40         return false;
    41     }*/
    42 
    43     /*
    44     时间复杂度:
    45         最好情况:O(a)
    46         最坏情况:O(a+r)
    47         平均情况:O(a+r/2)
    48     空间复杂度:O(1)
    49      */
    50     public static boolean hasCircle(Node head) {
    51         // 创建快慢指针
    52         Node fast = head;
    53         Node slow = head;
    54         // 遍历链表
    55         do {
    56             // 快指针是否到达终点
    57             if (fast == null || fast.next == null) return false;
    58             fast = fast.next.next;
    59             slow = slow.next;
    60         } while (fast != slow);
    61         // fast == slow
    62         return true;
    63     }
    64 
    65     public static void main(String[] args) {
    66         // 1 --> 2 --> 3 --> 4
    67         /*Node head = new Node(4);
    68         head = new Node(3, head);
    69         head = new Node(2, head);
    70         head = new Node(1, head);
    71         System.out.println(hasCircle(head));*/
    72 
    73         // 1 --> 2 --> 3 --> 4 --> 2 --> ...
    74         /*Node node = new Node(4);
    75         Node head = new Node(3, node);
    76         head = new Node(2, head);
    77         node.next = head;
    78         head = new Node(1, head);
    79         System.out.println(hasCircle(head));*/
    80 
    81         // 1 --> 2 --> 3 --> 4 --> 4 --> ...
    82         Node node = new Node(4);
    83         node.next = node;
    84         Node head = new Node(3, node);
    85         head = new Node(2, head);
    86         head = new Node(1, head);
    87         System.out.println(hasCircle(head));
    88     }
    89 }

    方法2. 跑道(快慢指针)

                                                              判断链表是否有环--快慢指针

     1 package com.cskaoyan.exercise;
     2 
     3 import java.util.Collection;
     4 import java.util.HashSet;
     5 
     6 /*
     7 如果有环:返回入环的第一个结点
     8 如果无环:返回null
     9 1. 迷雾森林
    10    Collection visited = new ArrayList();
    11    a.遍历链表,获取每一个结点。
    12      判断结点是否在visited集合中存在。
    13      存在:返回该节点
    14      不存在:将该结点添加到visited中,然后遍历下一个结点
    15    b.遍历结束后,返回null
    16 2. 跑道(快慢指针)
    17  */
    18 public class Ex2 {
    19     /*
    20     时间复杂度:O(n)
    21     空间复杂度:O(n)
    22      */
    23     /*public static Node hasCircle(Node head) {
    24         Collection visited = new HashSet();
    25         Node x = head;
    26         while (x != null) {
    27             if (visited.contains(x)) return x;
    28             visited.add(x);
    29             x = x.next;
    30         }
    31         return null;
    32     }*/
    33 
    34     /*
    35     时间复杂度:
    36         最好情况:O(2a)
    37         最坏情况:O(2a+r)
    38         平均情况:O(2a+r/2)
    39     空间复杂度:O(1)
    40      */
    41     public static Node hasCircle(Node head) {
    42         Node fast = head;
    43         Node slow = head;
    44         do {
    45             if (fast == null || fast.next == null) return null;
    46             fast = fast.next.next;
    47             slow = slow.next;
    48         } while (fast != slow);
    49         // fast == slow
    50         // 将fast移动到开头
    51         fast = head;
    52         while (fast != slow) {
    53             fast = fast.next;
    54             slow = slow.next;
    55         }
    56         // fast == slow 再一次相遇
    57         return fast;
    58     }
    59 
    60     public static void main(String[] args) {
    61         // 1 --> 2 --> 3 --> 4
    62         Node head = new Node(4);
    63         head = new Node(3, head);
    64         head = new Node(2, head);
    65         head = new Node(1, head);
    66         System.out.println(hasCircle(head));
    67 
    68         // 1 --> 2 --> 3 --> 4 --> 2 --> ...
    69         /*Node node = new Node(4);
    70         Node head = new Node(3, node);
    71         head = new Node(2, head);
    72         node.next = head;
    73         head = new Node(1, head);
    74         System.out.println(hasCircle(head));*/
    75 
    76         // 1 --> 2 --> 3 --> 4 --> 4 --> ...
    77         /*Node node = new Node(4);
    78         node.next = node;
    79         Node head = new Node(3, node);
    80         head = new Node(2, head);
    81         head = new Node(1, head);
    82         System.out.println(hasCircle(head));*/
    83     }
    84 }

    Ex3:反转单链表

    方法1:头插法

     1 package com.cskaoyan.exercise;
     2 
     3 /*
     4 反转单链表
     5 举例:
     6     输入:1 --> 2 --> 3 --> null
     7     输出:3 --> 2 --> 1 --> null
     8 1.头插法
     9 2.递归
    10  */
    11 public class Ex3 {
    12     public static Node reverse(Node head) {
    13         Node prev = null;
    14         Node curr = head;
    15         while (curr != null) {
    16             // 保留下一个结点
    17             Node next = curr.next;
    18             // 头插法
    19             curr.next = prev;
    20             prev = curr;
    21             // curr移动到下一个结点
    22             curr = next;
    23         }
    24         return prev;
    25     }
    26 
    27     public static void print(Node head) {
    28         Node x = head;
    29         while (x != null) {
    30             System.out.print(x.value);
    31             if (x.next != null) System.out.print(" --> ");
    32             x = x.next;
    33         }
    34         System.out.println();
    35     }
    36 
    37     public static void main(String[] args) {
    38         Node head = new Node(3);
    39         head = new Node(2, head);
    40         head = new Node(1, head);
    41         print(head);
    42         head = reverse(head);
    43         print(head);
    44     }
    45 }

     方法二:递归

  • 相关阅读:
    oracle的nvl函数的用法
    简单实用的MD5加密算法
    oracle触发器使用笔记
    Html学习
    连接字符串
    oracle触发器使用笔记2
    oracle中如何给有空值的数据排序
    Zend Frame 添加Smarty模板引擎
    HDU 2464 A Pair of Graph
    POJ 1466 Girls and Boys
  • 原文地址:https://www.cnblogs.com/dust2017/p/12892082.html
Copyright © 2011-2022 走看看