刷題筆記2020-06-26

1.給定一個非空整數數組,除了某個元素只出現一次以外,其餘每個元素均出現兩次。找出那個只出現了一次的元素。

leetcode136

def singleNumber(self, nums: List[int]) -> int:
        res = 0
        for num in nums:
            res ^= num
        return res
  • 異或運算有以下三個性質:
  1. 任何數和 0 做異或運算,結果仍然是原來的數,即 a ^ 0 = a。
  2. 任何數和其自身做異或運算,結果是 0,即 a ^ a = 0。
  3. 異或運算滿足交換律和結合律,即 a ^ b ^ a = b ^ a ^ a = b ^ (a ^ a) = b ^ 0 = b。
  • 位運算
符號 運算規則
& 同爲1結果才爲1
| 同爲0結果才爲0
^ 相同爲0,不同爲1

2.使用堆排序方法排序(45,78,57,25,41,89),初始堆爲( )

A 78,45,57,25,41,89
B 89,78,57,25,41,45
C 89,78,25,45,41,57
D 89,45,78,41,57,25

  • 堆是具有以下性質的完全二叉樹:每個結點的值都大於或等於其子結點的值,稱爲大頂堆;或者每個結點的值都小於或等於其子結點的值,稱爲小頂堆。
    在這裏插入圖片描述
  • 對堆中的結點按層進行編號,將其映射到數組中:
    在這裏插入圖片描述
  • 堆排序的基本思路:
  1. 將無需序列構建成一個堆,升序採用大頂堆,降序採用小頂堆;
  2. 將堆頂元素與末尾元素交換,將最大元素"沉"到數組末端;
  3. 重新調整結構,使其滿足堆定義,然後繼續交換堆頂元素與當前末尾元素,直到整個序列有序。
/**
   * 調整大頂堆(僅是調整過程,建立在大頂堆已構建的基礎上)
   * @param arr
   * @param i
   * @param length
   */
  public static void adjustHeap(int []arr,int i,int length){
      int temp = arr[i];//先取出當前元素i
      for(int k=i*2+1;k<length;k=k*2+1){//從i結點的左子結點開始,也就是2i+1處開始
          if(k+1<length && arr[k]<arr[k+1]){//如果左子結點小於右子結點,k指向右子結點
              k++;
          }
          if(arr[k] >temp){//如果子節點大於父節點,將子節點值賦給父節點(不用進行交換)
              arr[i] = arr[k];
              i = k;
          }else{
              break;
          }
      }
      arr[i] = temp;//將temp值放到最終的位置
  }

答案:B

參考鏈接:https://www.cnblogs.com/chengxiao/p/6129630.html

3. 迴文數:判斷一個整數是否是迴文數。迴文數是指正序(從左向右)和倒序(從右向左)讀都是一樣的整數。

leetcode9

class Solution {
    public boolean isPalindrome(int x) {
        // 特殊情況:
        // 如上所述,當 x < 0 時,x 不是迴文數。
        // 同樣地,如果數字的最後一位是 0,爲了使該數字爲迴文,
        // 則其第一位數字也應該是 0
        // 只有 0 滿足這一屬性
        if (x < 0 || (x % 10 == 0 && x != 0)) {
            return false;
        }

        int revertedNumber = 0;
        // 反轉一半數字
        while (x > revertedNumber) {
            revertedNumber = revertedNumber * 10 + x % 10;
            x /= 10;
        }

        // 當數字長度爲奇數時,我們可以通過 revertedNumber/10 去除處於中位的數字。
        // 例如,當輸入爲 12321 時,在 while 循環的末尾我們可以得到 x = 12,revertedNumber = 123,
        // 由於處於中位的數字不影響迴文(它總是與自己相等),所以我們可以簡單地將其去除。
        return x == revertedNumber || x == revertedNumber / 10;
    }
}
  • 整數反轉的數學方法:
//pop operation:
pop = x % 10;
x /= 10;
//push operation:
temp = rev * 10 + pop;
rev = temp;

4. 六個圓盤的漢諾塔,總的移動次數是( )

Hanoi(n, a, b):將n個盤子從a柱移到b柱。
f(n):n個盤子的漢諾塔的總移動次數。

  • Hanoi(n, a, c) = Hanoi(n-1, a, b) + 1 + Hanoi(n-1, b, c):假設有a、b、c三個柱,要將a上n個盤子移到c,先將a上面n-1個盤子移到b,再將a最下面的盤子移到c,最後將b上的n-1個盤子移到c。
  • n盤子漢諾塔問題變成了移動一個盤子 + 兩個n-1盤子漢諾塔問題:
    f(n)=f(n1)+1+f(n1)=2f(n1)+1f(n)+1=2(f(n1)+1)f(n)+1=2(n1)(f(1)+1)f(n)+1=2nf(n)=2n1 f(n) = f(n-1) + 1 + f(n-1) = 2f(n-1) + 1 \\ f(n) + 1 = 2(f(n-1) + 1) \\ f(n) + 1 = 2^{(n-1)} (f(1) + 1) \\ f(n) + 1 = 2^n \\ f(n) = 2^n -1
    答案:2^6 - 1 = 63

5. 設哈希表長度爲11,哈希函數爲Hash(key)=key%11。存在關鍵碼{47,7,29,11,9,84,54,20,30},採用二次探測法處理衝突,建立的hash表爲( )

  • 平方探測法:以增量序列 12,12,22,22,...,q2,q21^2, -1^2, 2^2, -2^2, ... , q^2, -q^2 且 q<=TableSize/2 循環試探下一個存儲地址。
  • 一個結論:如果哈希表大小是4k+3的素數(7、11、19),那麼只要有空位,就一定能夠找的着。
    在這裏插入圖片描述
    參考地址:https://zhuanlan.zhihu.com/p/34520264

6. 有關希爾排序算法敘述正確的是( )

A.最後一次的步長增量一定爲1
B.分割後子序列內部的排序算法是直接插入排序
C.分割後子序列內部的排序算法是直接選擇排序
D.希爾排序是穩定排序算法

  • 希爾排序的步驟:
  1. 選擇增量gap = length/2爲起始,以gap = gap/2的方式縮小增量,此增量序列可表示爲{n/2, (n/2)/2 , …, 1};
  2. 通過這個增量將數組元素劃分爲若干組,分組進行插入排序;
  3. 然後逐步縮小增量,繼續分組進行插入排序,直至增量爲1。
    在這裏插入圖片描述
/**
 * 希爾排序 針對有序序列在插入時採用移動法。
 * @param arr
 */
public static void sort1(int []arr){
    //增量gap,並逐步縮小增量
    for(int gap=arr.length/2;gap>0;gap/=2){
        //從第gap個元素,逐個對其所在組進行直接插入排序操作
        for(int i=gap;i<arr.length;i++){
            int j = i;
            int temp = arr[j];
            if(arr[j]<arr[j-gap]){
                while(j-gap>=0 && temp<arr[j-gap]){
                    //移動法
                    arr[j] = arr[j-gap];
                    j-=gap;
                }
                arr[j] = temp;
            }
        }
    }
}

正確答案: A B
參考鏈接:https://www.cnblogs.com/chengxiao/p/6104371.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章