徒手挖地球十四周目

徒手挖地球十四周目

NO.48 旋轉圖像 中等

在這裏插入圖片描述
在這裏插入圖片描述
思路一:先轉置矩陣,再列對換 很好理解先將圖像矩陣轉置,再將轉置之後的圖像矩陣列對換就得到了順時針旋轉90°的效果。把示例在紙上模擬一下就很清楚了:

在這裏插入圖片描述

public void rotate(int[][] matrix) {
    if (matrix==null)return;
    //轉置矩陣
    for (int i=0;i<matrix.length;i++){
        for (int j=i;j<matrix[i].length;j++){
            int temp=matrix[i][j];
            matrix[i][j]=matrix[j][i];
            matrix[j][i]=temp;
        }
    }
    //列對換
    for (int i=0;i<matrix.length/2;i++){
        for (int j=0;j<matrix.length;j++){
            int temp=matrix[j][i];
            matrix[j][i]=matrix[j][matrix.length-1-i];
            matrix[j][matrix.length-1-i]=temp;
        }
    }
}

時間複雜度:O(n^2)

NO.49 字母異位詞分組 中等

在這裏插入圖片描述

思路一:算術基本定理法 這是一個非常巧妙的方法。

算術基本定理(唯一分解定理): 任何一個大於 1 的自然數都可以分解成一些素數的乘積;並且在不計次序的情況下,這種分解方式是唯一的。 ——歐幾里得

  1. 先申請一個包含26個不重複素數的數組prime[ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103 ],一個HashMap<Interger,List<String>>。
  2. 將字符串的每個字符減去’a’映射出對應的素數,將字符串和其映射出的素數的乘積作爲鍵值對保存到哈希表中,最後哈希表中的所有List<String>作爲結果集即可。
public List<List<String>> groupAnagrams(String[] strs) {
    if (strs==null||strs.length==0)return new ArrayList<>();
    //26個字母分別對應一個素數
    int[] prime=new int[]{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103};
    HashMap<Integer,List<String>> map=new HashMap<>();
    for (int i=0;i<strs.length;i++){
        int key=1;
        for (int j=0;j<strs[i].length();j++){
            //字符串的每個字符對應的素數的乘積key
            key*=prime[strs[i].charAt(j)-'a'];
        }
        if (map.containsKey(key)){
            map.get(key).add(strs[i]);
        }else {
            map.put(key,new ArrayList<String>());
            map.get(key).add(strs[i]);
        }
    }
    return new ArrayList<>(map.values());
}

**ps:此方法有一個嚴重的問題,key很容易發生溢出。**最直接的解決方法就是採用大數類型的key。

時間複雜度:O(n*k),k是字符串的最大長度

思路二:排序數組分類法 申請一個HashMap<String,List>,將每個字符串中的字符按照字典順序排序後作爲key、字符串本身作爲value中的集合的元素。

public List<List<String>> groupAnagrams(String[] strs) {
    if (strs==null||strs.length==0)return new ArrayList<>();
    HashMap<String,List<String>> map=new HashMap<>();
    //遍歷每個字符串
    for (int i=0;i<strs.length;i++){
        //將麼個字符串中的字符按字典排序後作爲key
        char[] chars = strs[i].toCharArray();
        Arrays.sort(chars);
        String key = String.valueOf(chars);
        //key作爲key,strs[i]作爲value集合中的元素
        if (!map.containsKey(key))map.put(key,new ArrayList<>());
        map.get(key).add(strs[i]);
    }
    return new ArrayList<>(map.values());
}

時間複雜度:O(n*klogk) n爲元素個數,k爲最長字符串長度,klogk是排序的時間複雜度

思路三:字符計數分類法 和思路三差不多的想法,申請一個HashMap<String,List>,將每個字符串中字符出現的字數統計之後轉換成"n#n#n#n#…“形式的字符串作爲key。例如abc轉換爲"1#1#1#0#0#…”。

public List<List<String>> groupAnagrams(String[] strs) {
    if (strs==null||strs.length==0)return new ArrayList<>();
    HashMap<String,List<String>> map=new HashMap<>();
    for (int i=0;i<strs.length;i++){
        //統計字符串中每個字符出現的次數
        int[] count=new int[26];
        for (int j=0;j<strs[i].length();j++){
            count[strs[i].charAt(j)-'a']++;
        }
        //將計數器轉換成n#n#n#n#格式
        String key="";
        for (int k=0;k<count.length;k++){
            key+=count[k]+"#";
        }
        if (!map.containsKey(key))map.put(key,new ArrayList<>());
        map.get(key).add(strs[i]);
    }
    return new ArrayList<>(map.values());
}

時間複雜度:O(nk),k是最長字符串的長度

NO.50 Pow(x,n) 中等

在這裏插入圖片描述

思路一:暴力法 這道題暴力法是不能通過leetcode判題機,會得到一個t。但是方法本身是可以得到正確答案的,所以我們需要對他進行優化。暴力法的想法很簡單的:2^3=2*2*2。

如果n爲負,則n=-n同時x=1/x,例如2^(-3)=1/2*1/2*1/2。但是這裏要注意n的取值範圍,主要是 正整數和負整數的不同範圍限制 。

public double myPow(double x, int n) {
    if (x==0)return 0;
    if (n==0)return 1;
    double ans=1;
    long N=n;
    if (N<0){
        N=-N;
        x=1/x;
    }
    for (int i=0;i<N;i++){
        ans*=x;
    }
    return ans;
}

時間複雜度:O(n)

思路二:二分法 當我們得到x^(n/2)的時候,我們不需要再去乘上n/2個x了,而是x^(n/2)*x^(n/2)=x^n。

這個想法用遞歸很容易實現,但是需要注意的是n的奇偶性,如果n爲奇數則需要再乘上一個x。

public double myPow(double x, int n) {
    switch (n){
        case 1:return x;
        case 0:return 1;
        case -1:return 1/x;
    }
    double half=myPow(x,n/2);
    //奇偶性處理
    double rest=myPow(x,n%2);
    return half*half*rest;
}

時間複雜度:O(logn)

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