<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
        My Github

      劍指Offer面試題:31.兩個鏈表的第一個公共節點

      一、題目:兩個鏈表的第一個公共節點

      題目:輸入兩個鏈表,找出它們的第一個公共結點。

        鏈表結點定義如下,這里使用C#語言描述:

          public class Node
          {
              public int key;
              public Node nextNode;
      
              public Node(int key)
              {
                  this.key = key;
              }
          }

      二、解題思路

      2.1 蠻力法

        碰到這道題,很多人的第一反應就是蠻力法:在第一鏈表上順序遍歷每個結點,每遍歷到一個結點的時候,在第二個鏈表上順序遍歷每個結點。如果在第二個鏈表上有一個結點和第一個鏈表上的結點一樣,說明兩個鏈表在這個結點上重合,于是就找到了它們的公共結點。如果第一個鏈表的長度為m,第二個鏈表的長度為n,顯然該方法的時間復雜度是O(mn)

      2.2 借助外部空間法

        首先,經過分析我們發現兩個有公共結點而部分重合的鏈表,拓撲形狀看起來像一個Y,而不可能像X,如下圖所示,兩個鏈表在值為6的結點處交匯:

        如果兩個鏈表有公共結點,那么公共結點出現在兩個鏈表的尾部。如果我們從兩個鏈表的尾部開始往前比較,最后一個相同的結點就是我們要找的結點。But,在單鏈表中只能從頭結點開始按順序遍歷,最后才能到達尾結點。最后到達的尾結點卻要最先被比較,這是“后進先出”的特性。于是,我們可以使用棧的特點來解決這個問題:分別把兩個鏈表的結點放入兩個棧里,這樣兩個鏈表的尾結點就位于兩個棧的棧頂,接下來比較兩個棧頂的結點是否相同。如果相同,則把棧頂彈出接著比較下一個棧頂,直到找到最后一個相同的結點

          public static Node FindFirstCommonNode(Node head1, Node head2)
          {
              if(head1 == null || head2 == null)
              {
                  return null;
              }
      
              Stack<Node> stack1 = new Stack<Node>();
              Stack<Node> stack2 = new Stack<Node>();
      
              while(head1 != null)
              {
                  stack1.Push(head1);
                  head1 = head1.nextNode;
              }
      
              while(head2 != null)
              {
                  stack2.Push(head2);
                  head2 = head2.nextNode;
              }
      
              Node node1 = null;
              Node node2 = null;
              Node common = null;
      
              while(stack1.Count > 0 && stack2.Count > 0)
              {
                  node1 = stack1.Peek();
                  node2 = stack2.Peek();
      
                  if (node1.key == node2.key)
                  {
                      common = node1;
                      stack1.Pop();
                      stack2.Pop();
                  }
                  else
                  {
                      break;
                  }
              }
      
              return common;
          }

        在上述思路中,我們需要用兩個輔助棧。如果鏈表的長度分別為m和n,那么空間復雜度是O(m+n)。這種思路的時間復雜度也是O(m+n)。和最開始的蠻力法相比,時間效率得到了提高,相當于是用空間消耗換取了時間效率

      2.3 不借助外部空間法

        那么,可不可以不借助棧來實現了呢?答案是可以的,我們可以首先遍歷兩個鏈表得到它們的長度,就能知道哪個鏈表比較長,以及長的鏈表比短的鏈表多幾個結點。在第二次遍歷的時候,在較長的鏈表上先走若干步,接著再同時在兩個鏈表上遍歷,找到的第一個相同的結點就是它們的第一個公共結點

        比如在上圖的兩個鏈表中,我們可以先遍歷一次得到它們的長度分別為5和4,也就是較長的鏈表與較短的鏈表相比多一個結點。第二次先在長的鏈表上走1步,到達結點2。接下來分別從結點2和結點4出發同時遍歷兩個結點,直到找到它們第一個相同的結點6,這就是我們想要的結果。

          public static Node FindFirstCommonNode(Node head1, Node head2)
          {
              // 得到兩個鏈表的長度
              int length1 = GetListLength(head1);
              int length2 = GetListLength(head2);
              int diff = length1 - length2;
      
              Node headLong = head1;
              Node headShort = head2;
              if (diff < 0)
              {
                  headLong = head2;
                  headShort = head1;
                  diff = length2 - length1;
              }
              // 先在長鏈表上走幾步
              for (int i = 0; i < diff; i++)
              {
                  headLong = headLong.nextNode;
              }
              // 再同時在兩個鏈表上遍歷
              while (headLong != null && headShort != null && headLong != headShort)
              {
                  headLong = headLong.nextNode;
                  headShort = headShort.nextNode;
              }
      
              Node commonNode = headLong;
              return commonNode;
          }
      
          private static int GetListLength(Node head)
          {
              int length = 0;
              Node tempNode = head;
              while (tempNode != null)
              {
                  tempNode = tempNode.nextNode;
                  length++;
              }
      
              return length;
          }

        上述思路與借助棧的方法的時間復雜度都是O(m+n),但我們不再需要輔助的棧,因此提高了空間效率。

      三、單元測試

      3.1 測試用例:功能測試與特殊輸入測試

          [TestClass]
          public class CommonNodeHelperTest
          {
              private void DestoryNode(Node node)
              {
                  if (node != null)
                  {
                      node = null;
                  }
              }
      
              // 第一個公共結點在鏈表中間
              // 1 - 2 - 3 \
              //            6 - 7
              //     4 - 5 /
              [TestMethod]
              public void FindTest1()
              {
                  Node node1 = new Node(1);
                  Node node2 = new Node(2);
                  Node node3 = new Node(3);
                  Node node4 = new Node(4);
                  Node node5 = new Node(5);
                  Node node6 = new Node(6);
                  Node node7 = new Node(7);
      
                  // first
                  node1.nextNode = node2;
                  node2.nextNode = node3;
                  node3.nextNode = node6;
                  node6.nextNode = node7;
                  // second
                  node4.nextNode = node5;
                  node5.nextNode = node6;
      
                  Node actual = CommonNodeHelper.FindFirstCommonNode(node1, node4);
                  Assert.AreEqual(actual.key, 6);
      
                  DestoryNode(node1);
                  DestoryNode(node2);
                  DestoryNode(node3);
                  DestoryNode(node4);
                  DestoryNode(node5);
                  DestoryNode(node6);
                  DestoryNode(node7);
              }
      
              // 沒有公共結點
              // 1 - 2 - 3 - 4
              //            
              // 5 - 6 - 7
              [TestMethod]
              public void FindTest2()
              {
                  Node node1 = new Node(1);
                  Node node2 = new Node(2);
                  Node node3 = new Node(3);
                  Node node4 = new Node(4);
                  Node node5 = new Node(5);
                  Node node6 = new Node(6);
                  Node node7 = new Node(7);
      
                  // first
                  node1.nextNode = node2;
                  node2.nextNode = node3;
                  node3.nextNode = node4;
                  
                  // second
                  node5.nextNode = node6;
                  node6.nextNode = node7;
      
                  Node actual = CommonNodeHelper.FindFirstCommonNode(node1, node5);
                  Assert.AreEqual(actual, null);
      
                  DestoryNode(node1);
                  DestoryNode(node2);
                  DestoryNode(node3);
                  DestoryNode(node4);
                  DestoryNode(node5);
                  DestoryNode(node6);
                  DestoryNode(node7);
              }
      
              // 公共結點是最后一個結點
              //         5 - 6 \
              //                7
              // 1 - 2 - 3 - 4 /
              [TestMethod]
              public void FindTest3()
              {
                  Node node1 = new Node(1);
                  Node node2 = new Node(2);
                  Node node3 = new Node(3);
                  Node node4 = new Node(4);
                  Node node5 = new Node(5);
                  Node node6 = new Node(6);
                  Node node7 = new Node(7);
      
                  // first
                  node1.nextNode = node2;
                  node2.nextNode = node3;
                  node3.nextNode = node4;
                  node4.nextNode = node7;
                  // second
                  node5.nextNode = node6;
                  node6.nextNode = node7;
      
                  Node actual = CommonNodeHelper.FindFirstCommonNode(node5, node1);
                  Assert.AreEqual(actual.key, 7);
      
                  DestoryNode(node1);
                  DestoryNode(node2);
                  DestoryNode(node3);
                  DestoryNode(node4);
                  DestoryNode(node5);
                  DestoryNode(node6);
                  DestoryNode(node7);
              }
      
              // 公共結點是第一個結點
              // 1 - 2 - 3 - 4 - 5
              // 兩個鏈表完全重合   
              [TestMethod]
              public void FindTest4()
              {
                  Node node1 = new Node(1);
                  Node node2 = new Node(2);
                  Node node3 = new Node(3);
                  Node node4 = new Node(4);
                  Node node5 = new Node(5);
                  Node node6 = new Node(6);
                  Node node7 = new Node(7);
      
                  // first & second
                  node1.nextNode = node2;
                  node2.nextNode = node3;
                  node3.nextNode = node4;
                  node4.nextNode = node5;
      
                  Node actual = CommonNodeHelper.FindFirstCommonNode(node1, node1);
                  Assert.AreEqual(actual.key, 1);
      
                  DestoryNode(node1);
                  DestoryNode(node2);
                  DestoryNode(node3);
                  DestoryNode(node4);
                  DestoryNode(node5);
                  DestoryNode(node6);
                  DestoryNode(node7);
              }
      
              // 輸入的兩個鏈表有一個空鏈表
              [TestMethod]
              public void FindTest5()
              {
                  Node node1 = new Node(1);
                  Node node2 = new Node(2);
                  Node node3 = new Node(3);
                  Node node4 = new Node(4);
                  Node node5 = new Node(5);
      
                  // first & second
                  node1.nextNode = node2;
                  node2.nextNode = node3;
                  node3.nextNode = node4;
                  node4.nextNode = node5;
      
                  Node actual = CommonNodeHelper.FindFirstCommonNode(node1, null);
                  Assert.AreEqual(actual, null);
      
                  DestoryNode(node1);
                  DestoryNode(node2);
                  DestoryNode(node3);
                  DestoryNode(node4);
                  DestoryNode(node5);
              }
      
              // 輸入的兩個鏈表均為空鏈表
              [TestMethod]
              public void FindTest6()
              {
                  Node actual = CommonNodeHelper.FindFirstCommonNode(null, null);
                  Assert.AreEqual(actual, null);
              }
          }

      3.2 測試結果:用例通過情況與代碼覆蓋率

        (1)用例通過情況

        (2)代碼覆蓋率

       

      posted @ 2015-09-20 00:23  EdisonZhou  閱讀(8299)  評論(1)    收藏  舉報
      主站蜘蛛池模板: 国产91麻豆视频免费看| 亚洲a∨国产av综合av下载| 国产精品久久蜜臀av| www插插插无码免费视频网站| 亚洲人成电影在线天堂色| 人妻在线无码一区二区三区| 色狠狠色噜噜AV一区| 天天做天天爱夜夜夜爽毛片| 老少配老妇老熟女中文普通话| 亚洲人成色7777在线观看不卡| 久久精品国产色蜜蜜麻豆| 高潮潮喷奶水飞溅视频无码| 亚洲日本韩国欧美云霸高清| 特级做a爰片毛片免费看无码| 激情伊人五月天久久综合 | 免费国产拍久久受拍久久| 好姑娘高清影视在线观看| 永平县| 99久久免费精品色老| 国内久久人妻风流av免费 | 乐昌市| 国产自拍一区二区三区在线| 日本高清在线观看WWW色| 免费视频爱爱太爽了| 福利网午夜视频一区二区| 精品日韩人妻中文字幕| 推油少妇久久99久久99久久| 国内自产少妇自拍区免费| 国产成人a在线观看视频免费| 亚洲精品美女久久久久99| 蜜臀av一区二区三区在线| 亚洲国产在一区二区三区| 日本黄漫动漫在线观看视频| 国产精品夫妇激情啪发布| 成 人 色 网 站免费观看| 精品国产大片中文字幕| 嫩草欧美曰韩国产大片| 精品亚洲国产成人av| 丝袜人妻一区二区三区网站| 久久夜色精品国产亚av| 亚洲国产成人精品福利无码|