美文网首页
算法通关2.数组和链表

算法通关2.数组和链表

作者: YangDxg | 来源:发表于2019-08-21 14:49 被阅读0次

    数组

    数组:内存里连续的一段存储区域

    取:取元素时间复杂度为O(1)

    插入:需要挪动插入位置后面的元素,时间复杂度为O(n)

    删除:同插入,后面的元素需要向前挪动,时间复杂度为O(n)

    链表

    单向链表:用一个指针链向下一个元素

    双向链表:用俩个指针链向上一个元素和下一个元素

    增加删除只需要更改指针指向即可,时间复杂度O(1)

    查找时间复杂度是O(n)

    练习

    1. leetcode206反转链表

      输入: 1->2->3->4->5->NULL
      输出: 5->4->3->2->1->NULL
      

      思路:定义俩个变量,记录当前节点和上一个节点,采用俩数交换的方式进行反转

      class Solution {
          public ListNode reverseList(ListNode head) {
              ListNode cur = head;
              ListNode prev = null;
              ListNode tempNext = null;
              while (cur != null) {
                  tempNext = cur.next;
                  cur.next = prev;
                  prev = cur;
                  cur = tempNext;
              }
              return prev;
          }
      }
      
    2. leetcode24两两交互链表中的节点

      给定 1->2->3->4, 你应该返回 2->1->4->3.
      

      递归解乏

          public static ListNode swapPairs(ListNode head) {
              if (head == null || head.next == null) {
                  return head;
              }
              ListNode next = head.next;
              head.next = swapPairs(next.next);
              next.next = head;
              return next;
          }
      

      非递归解法

          public static ListNode swapPairs2(ListNode head) {
              ListNode prev = new ListNode(0);
              prev.next = head;
              ListNode temp = prev;
              while (temp.next != null && temp.next.next != null) {
                  ListNode start = temp.next;
                  ListNode end = temp.next.next;
                  temp.next = end;
                  start.next = end.next;
                  end.next = start;
                  temp = start;
              }
              return prev.next;
          }
      
    3. 环形链表

      给定一个链表,判断链表中是否有环。

      输入:head = [3,2,0,-4], pos = 1
      输出:true
      解释:链表中有一个环,其尾部连接到第二个节点。
      
      img

    思路:如何判断一个链表是否有环

    1. 硬做(在0.5s内判断会不会走到null,性能很差)

    2. 把走过的节点放到set中,每到新节点判断set中有没有进行判重,时间复杂度O(n)

          public boolean hasCycle(ListNode head) {
              Set<ListNode> nodes = new HashSet<>();
              while (head != null) {
                  if (nodes.contains(head)) {
                      return true;
                  }
                  nodes.add(head);
                  head = head.next;
              }
              return false;
          }
      
    3. 龟兔赛跑式(快慢指针),快指针每次走俩步,慢指针每次走一步,快慢相遇说明有环

          public boolean hasCycle(ListNode head) {
              if (head == null || head.next == null) {
                  return false;
              }
              ListNode fast = head;
              ListNode slow = head;
              while (fast.next != null && fast.next.next != null) {
                  slow = slow.next;
                  fast = fast.next.next;
                  if (slow == fast) {
                      return true;
                  }
              }
              return false;
          }
      

    相关文章

      网友评论

          本文标题:算法通关2.数组和链表

          本文链接:https://www.haomeiwen.com/subject/rsobsctx.html