第三週LeetCode算法題兩道

第一道

題目名稱:46. Permutations

題目難度:Medium

題目描述:Given a collection of distinct numbers, return all possible permutations.

For example,
[1,2,3] have the following permutations:

[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]

題目分析:
題目的意思就是給你一個沒有重複數字的序列,要你找出這個序列中的數字的所有可能的組合情況。

可以非常自然地想到使用遞歸來解決這個問題。假設序列中數字的個數是n。我們初始的新序列爲空。每一層遞歸遍歷所有可以添加進這個新序列的情況。

比如例子中的1 2 3,第一層遞歸時,將新序列第一位可能的所有情況都遍歷到。這樣第一層遞歸之後新序列就有三種情況:[1]、[2]、[3],然後再在給定序列中,刪除已經被使用的數字。例子中給定序列是[1,2,3],那麼進入第二層的給定序列分別是:[2,3]、[1,3]、[1,2]。
這樣,每一層遍歷使用給定序列中的一個數,遞歸結束的條件是給定序列中的數字已經全部被使用。也就是說,給定序列的大小爲0。

最後AC的代碼如下:

class Solution {
public:
    void nextOne(vector<vector<int> > & result, vector<int> current, vector<int> nums) {
        if (nums.size() == 0) {
            result.push_back(current);
            return;
        }
        for (vector<int>::iterator it = nums.begin(); it!=nums.end(); it++) {
            //新建一個當前未用數字序列的副本以用於之後的恢復
            vector<int> temp(nums);
            //這裏重新new一個副本newCur是因爲循環的每次都需要對current的序列作操作,但是這些操作又不能相互影響
            vector<int> newCur(current);
            //將一種新的情況添加到當前序列
            newCur.push_back(*it);
            //刪除未用序列中剛剛已經被我麼使用的數字
            nums.erase(it);
            nextOne(result, newCur, nums);
            //因爲刪除操作在每次循環中不能相互影響,所以這裏要做一個“恢復”的操作
            nums = temp;
        }
    }
    vector<vector<int>> permute(vector<int>& nums) {
        vector<vector<int> > result;
        vector<int> current;
        nextOne(result, current, nums);
        return result;
    }
};

需要特別小心的是,遞歸時,什麼參數可以使用其“引用“,什麼參數需要重新建立一個副本。解題過程中題主也在這裏掉過一個坑,相關的內容已寫在代碼註釋中。


第二道

題目名稱:14. Longest Common Prefix

題目難度:easy

題目描述:Write a function to find the longest common prefix string amongst an array of strings.

題目分析:
這道題要求我們找出所給的一系列字符串中公共的最長的前綴。思路特別簡單:
先遍歷一遍數組,找出長度最短的字符串。這個字符串最有可能成爲“最長的公共前綴“。然後就從頭到尾遍歷這個候選者包含的字符,對於每一個字符,檢查所給的字符串集合中每一個字符串對應的位置的字符是否相同。如果所有字符串對應位置的字符串都與之相同,那末將這個字符加入“結果字符串“result中,然後進入下一位字符的比較。如果不同,則已經找到了最長的公共前綴。

最後AC的代碼如下:

class Solution {
public:
    bool common(char c, int index, vector<string>& strs) {
      for (int i = 0; i < strs.size(); i++) {
        if (strs[i][index] != c)
          return false;
      }
      return true;
    }

    string longestCommonPrefix(vector<string>& strs) {
      if(strs.size()==0)
      return "";
      int size = 100000;
      string candidate, result = "";
      for (int i = 0; i < strs.size(); ++i) {
        if (strs[i].size() < size) {
          size = strs[i].size();
          candidate = strs[i];
        }
      }
      for (int i = 0; i < size; i++) {
        if (common(candidate[i], i, strs)) {
          result += candidate[i];
        } else {
          return result;
        }
      }
      return result;
    }
};

需要注意的是測試樣例中有空輸入的情況,這種情況需要特殊處理。

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