第九周LeetCode算法題兩道

第一道

題目名稱:49. Group Anagrams

題目難度:Medium

題目描述:Given an array of strings, group anagrams together.

For example, given: [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”],
Return:

[
  ["ate", "eat","tea"],
  ["nat","tan"],
  ["bat"]
]

Note: All inputs will be in lower-case.

題目分析:
題目要求我們將輸入的字符串分類。分類的依據是含有相同的字母且相同字母對應的數量相等。

思路很簡單直接。既然在同一組的每個字符串之間不同的只是字母的順序,那麼將他們的字母都排序後,同一組的字符串排序的結果一定相等。這樣我們就將它們分類開來了。

排序用的是一個char類型的multiset容器。

最終AC的代碼是:

class Solution {
public:
    vector<vector<string> > groupAnagrams(vector<string>& strs) {
        vector<vector<string> > result;
        vector<string> sort;
        for (int i = 0; i < strs.size(); ++i) {
            multiset<char> temp_set;
            string tStr = "";
            for (int j = 0; j < strs[i].size();++j) {
                temp_set.insert(strs[i][j]);
            }
            for (set<char>::iterator it = temp_set.begin(); it != temp_set.end(); ++it) {
                tStr += *it;
            }
            sort.push_back(tStr);
        }
        bool visit[strs.size()];
        memset(visit, 0, sizeof(visit));
        for (int i = 0; i < strs.size(); ++i) {
            vector<string> temp;
            if (visit[i] == 0) {
                temp.push_back(strs[i]);
                visit[i] = 1;
                for (int j = i + 1; j < strs.size(); ++j) {
                    if (sort[j] == sort[i]) {
                        temp.push_back(strs[j]);
                        visit[j] = 1;
                    }
                }
            }
            if (temp.size() != 0)
                result.push_back(temp);
        }
        return result;
    }
};

第二道

題目名稱:33. Search in Rotated Sorted Array

題目難度:Medium

題目描述:Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

You are given a target value to search. If found in the array return its index, otherwise return -1.

You may assume no duplicate exists in the array.

題目分析:
本題乍一看好像特別簡單。就是在一個數組之內找一個指定的值。這樣好像直接暴力搜索遍歷一遍數組就好了。但是這樣的話這道題爲什麼不歸類到“easy“難度呢?那就說明了這道題有可能對運行時間有限制,O(n)的時間肯定是過不了了。但是抱着試一試的心態,我跑了一次O(n)級別的搜索,居然直接過了!但是感覺這道題肯定不是這麼簡單。
於是到題目的討論區看了看。最高記錄是用二分查找法來做的。它的做法是:先用二分查找找出數組最小的一個數,這個數所在的位置也就是數組旋轉的支點。這樣子直接將target目標數可能在的範圍直接限制在由這個支點分開的兩個不同範圍其中一個。然後再從這個新範圍中做經典的二分查找搜索(此時的新範圍已經排好序了)

最後AC的我的算法是:(暴力搜索)

class Solution {
public:
    int search(vector<int>& nums, int target) {
        bool flag = false;
        for (int i = 0; i < nums.size(); ++i) {
            if (nums[i] == target) {
                flag = true;
                return i;
            }
        }    
        if (flag == false)
            return -1;
    }
};

評論區中使用兩次二分搜索的代碼是:

class Solution {
public:
    int search(int A[], int n, int target) {
        int lo=0,hi=n-1;
        // find the index of the smallest value using binary search.
        // Loop will terminate since mid < hi, and lo or hi will shrink by at least 1.
        // Proof by contradiction that mid < hi: if mid==hi, then lo==hi and loop would have been terminated.
        while(lo<hi){
            int mid=(lo+hi)/2;
            if(A[mid]>A[hi]) lo=mid+1;
            else hi=mid;
        }
        // lo==hi is the index of the smallest value and also the number of places rotated.
        int rot=lo;
        lo=0;hi=n-1;
        // The usual binary search and accounting for rotation.
        while(lo<=hi){
            int mid=(lo+hi)/2;
            int realmid=(mid+rot)%n;
            if(A[realmid]==target)return realmid;
            if(A[realmid]<target)lo=mid+1;
            else hi=mid-1;
        }
        return -1;
    }
};

有一點比較有意思的是,我參考了評論區二分搜索的代碼重新寫了一次之後,發現運行時間還不如我原來的O(n)算法。個人覺得一個可以解釋的原因是,當數據量很大的時候,logN算法肯定是優於N算法的,但數據較小的時候,前者時間比後者長屬於正常現象。

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