neverend的日志

          不記錄,終將被遺忘。 一萬年太久,只爭朝夕。 他們用數字構建了整個世界。

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            62 Posts :: 1 Stories :: 17 Comments :: 0 Trackbacks


          2.1求8位二進制數中1的個數
          解法1:直觀法,每次除以2,計算余數為1的個數 O(log2v)
          解法2:簡單位操作,每次與0x01做與運算,再右移一位。O(log2v)
          解法3:使用位操作v & (v-1) , 每次可減少二進制數字中的一個1。(若v & (v-1) == 0, 則v為2的方冪)
          解法4:空間換時間,利用題目中字長8位的破綻,建立一個窮舉數組。O(1)

          知識點:位運算的性質
          附:數組有2n+1個數,其中n個數成對出現,找出非成對出現的那個數。
          數組所有元素做異或操作。

          2.2
          1.N!的末尾有多少個零
          2.N!二進制表示中最低位1的位置

          1.解法:質因數分解可知,0只有2*5可得,所以0的個數就是質因數分解中2的個數與5的個數的最小值,實際上就是
          求5的個數Z。
          Z= [N/5] + [N/5^2] +[N/5^3]+ ……
          [N/5]表示不大于N的數中5的倍數貢獻一個5
          [N/5^2]表示不大于N的數中5^2再貢獻一個5/。

          2.解法:因為質因數分解中只有2是偶數,所以Z = [N/2] + [N/2^2] + [N/2^3] + …… +

          2.3尋找多數元素問題
          解法:減治:每次刪除兩個不同的ID,水王ID出現的次數仍舊會超過總數的一半。

          2.4從1到N的所有數中“1”出現的個數
          解法:尋找1出現的規律,比較復雜。

          2.5尋找N個整數中最大的K個數
          解法1:選擇排序,選出最大的K個數。 O(n*k)
           一點改進:部分堆排序,先建堆,再排出最大的k個數即可。O(n)+O(logn*k)
          解法2:分治,利用快速排序的劃分思路。O(n*log2k)
          解法3:二分搜索(與《編程珠璣》第二章問題A思路類似),有兩種劃分方式:
          1.設已知N個數中最小值Vmin,最大值Vmax,對區間[Vmin, Vmax]做二分即可。
          2.設N個整數是M位長的。從最高位開始,按bi位0、1二分。
          此解法適用于大數據量的處理,不過要多次讀寫若干個臨時文件。
          解法4:建一個最小堆存儲K個數,堆頂為堆中最小值。
          對第k到N個數,若A[i]大于堆頂H[0],令H[0]=A[i],再調用shift-down過程調整堆。
          此解法非常適合于N值很大的情況,復雜度為O(n * log2k)
          解法5:空間換時間,用count[Vmax]計算每個數字出現的次數。
          如果Vmax很大,將[0, Vmax]分成m個小塊,再分別討論即可。

          2.7最大公約數問題
           用位運算求解
             位運算問題:
             1.求一個整數的二進制表示中1的個數
             2.逆轉一個整數的二進制表示問題

          2.9斐波那契數列
          ·遞歸 效率最低
          ·迭代 O(n)
          ·矩陣分治法

          2.14子數組之和的最大值
          分治
          動態規劃

          2.15子矩陣之和的最大值
          固定一維,另一維轉化為子數組之和的最大值問題

          2.16求數組中最長遞增字符列的長度

          解法1:動態規劃

          假設array[]的前i個元素中,最長遞增子序列的長度為LIS[i],

          則,LIS[i + 1] = max{1, LIS[k]+1}, array[i+1] > array[k], for any k<=i

          int LIS(int[] array) {
          int[] LIS = new int[array.length];
          for (int i = 0 ; i < array.length; i++) {
              LIS[i] 
          = 1;
              
          for (int j = 0; j<i; j++) {
                  
          if (array[i] > array[j] && LIS[j] + 1 >LIS[i])
                      LIS[i] 
          = LIS[j] + ; 
              }

          }

           

          O(N^2)的時間復雜度

          解法2:

          MLIS[i]定義為前i個元素中,以array[i]為最大元素的最長遞增子序列的長度。

          可以證明,MLIS[i]的最大值也是最終的結果。

          MaxV[i]保存長度為i的遞增子序列最大元素的最小值。

          解法2的程序更新MaxV的部分應該是有問題的,由此導致時間復雜度的分析錯誤,并且解法3也是錯誤的。


          2.17數組循環移位

          void rightshift(int *arr, int N, int k) {
              K 
          %= N;
              Reverse(arr, 
          0, N-k-1);
              Reverse(arr, N
          -k, N-1);
              Reverse(arr, 
          0, N-1);
          }

           

          數組問題思路:

          排序思路

          動態規劃

          看成一個數列或向量


          2.18數組分割


          3.1字符串移位包含的問題

          給定兩個字符串s1和s2,要求判定s2能否被s1做循環移位得到的字符串包含。例如:s1 = AABCD , s2 = CDAA,返回true. 給定s1 = ABCD 和 s2 = ACBD,返回false.

          解法1:模擬字符串移位的過程,判斷是否包含子串

          解法2:判斷s2是否為s1s1的子串即可。

          解法3:不申請空間,模擬判斷s2是否為s1s1子串的過程。

          思路:字符串可以抽象成向量來考慮。


          3.2電話號碼對應英語單詞

          類似于求冪集問題

          解法1:迭代,用while循環模擬

          解法2:遞歸

           

          3.3計算字符串相似度
          遞歸求解

          int calStrDis(char[] strA, int pABegin, int pAEnd, 
                      
          char[] strB, int pBBegin, int pBEnd) {
                  
          if (pABegin > pAEnd) {
                      
          if (pBBegin > pBEnd) {
                          
          return 0;
                      } 
          else {
                          
          return pBEnd - pBBegin + 1;
                      }
                  }
                  
                  
          if (pBBegin > pBEnd) {
                      
          if (pABegin > pAEnd) {
                          
          return 0;
                      } 
          else {
                          
          return pAEnd - pABegin + 1;
                      }
                  }
                  
                  
          if (strA[pABegin] == strB[pBBegin]) {
                      
          return calStrDis(strA, pABegin + 1, pAEnd, strB,
                              pBBegin 
          + 1, pBEnd);
                  } 
          else {
                      
          int t1 = calStrDis(strA, pABegin, pAEnd, strB, pBBegin + 1
                              pBEnd);
                      
          int t2 = calStrDis(strA, pABegin + 1, pAEnd, strB, pBBegin ,
                              pBEnd);
                      
          int t3 = calStrDis(strA, pABegin + 1, pAEnd, strB, pBBegin + 1 ,
                              pBEnd);
                      
          return min(t1, t2, t3) + 1;
                  }
              }
          遞歸優化,如何存儲子問題的解?

          3.4從無頭鏈表中刪除節點
          這個問題很無恥

          3.5最短摘要生成
          有空再看

          3.6編程判斷兩個鏈表是否相交
          轉化成鏈表是否有環的問題

          3.7隊列中取最大值操作
          可分解為兩個子問題
          子問題1:設計一個堆棧,使入棧,出棧,取最大值的時間復雜度都是O(1)。
          思路:用空間換時間,加一個數組link2NextMaxItem[],link2NextMaxItem[i]存儲的是前i個元素中最大值的下標。

          子問題2:用上述特性的兩個堆棧實現一個隊列
          堆棧A負責入隊,堆棧B負責出隊。當堆棧B空的時候,將堆棧A中的數據全部彈出并壓入堆棧B

          3.8 求二叉樹結點之間的最大距離
          動態規劃實現,還是不太懂。

          3.9重建二叉樹
          遞歸求解

          3.10分層遍歷二叉樹
          隊列遍歷二叉樹+變量標記層次

          3.11程序改錯
          編寫正確的二分搜索程序
          C代碼:

          int BinSearch(SeqList * R, int n , KeyType K )//在有序表R[0..n-1]中進行二分查找,成功時返回結點的位置,失敗時返回-1
          int low=0,high=n-1,mid; //置當前查找區間上、下界的初值
            if(R[low].key==K)
            
          {
            
          return 0
           ;
            }

            
          while(low<=high)//當前查找區間R[low..high]非空
            mid=low+((high-low)/2);//使用 (low + high) / 2 會有整數溢出的問題
            if(R[mid].key==K)
            
          {
            
          return mid; //查找成功返回

            }

            
          if(R[mid].key>K)
            high
          =mid-1//繼續在R[low..mid-1]中查找

            else
            low
          =mid+1; //繼續在R[mid+1..high]中查找
            }

            
          return -1; //當low>high時表示查找區間為空,查找失敗
            }
           //BinSeareh


          Java代碼:

          public static int binarySearch(int[] srcArray, int des)
            
          {
            
          int low = 0
          ;
            
          int high = srcArray.length-1
          ;
            
          while(low <= high) 
          {
            
          int middle = (low + high)/2
          ;
            
          if(des == srcArray[middle]) 
          {
            
          return
           middle;
            }
          else if(des <srcArray[middle]) {
            high 
          = middle - 1
          ;
            }
          else {
            low 
          = middle + 1
          ;
            }

            }

            
          return -1;
            }


          4.8三角形測試用例
          測試用例的三種類型:
          正常輸入 覆蓋功能點
          非法輸入 值域錯誤 類型錯誤
          邊界值輸入 0 1 MAX MIN 

          posted on 2010-09-29 11:10 neverend 閱讀(1253) 評論(0)  編輯  收藏 所屬分類: 筆記數據結構&算法

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 综艺| 财经| 泗洪县| 油尖旺区| 天峻县| 文昌市| 合肥市| 古蔺县| 日喀则市| 兴安盟| 永安市| 宜州市| 云南省| 西昌市| 凤凰县| 车险| 伽师县| 江达县| 威远县| 平潭县| 屏东市| 石家庄市| 丰县| 江华| 文山县| 宜春市| 措勤县| 永春县| 同心县| 阿鲁科尔沁旗| 西充县| 西乌珠穆沁旗| 昌平区| 阳西县| 万全县| 洪泽县| 婺源县| 厦门市| 利辛县| 遂昌县| 崇义县|