雙指針,集合問題-LeetCode 344、345、347、349、350

  • 2019 年 11 月 30 日
  • 筆記

作者:TeddyZhang

雙指針,集合問題:LeetCode #344 345 347 349 350

1

編程題

【LeetCode #344】反轉字元串

編寫一個函數,其作用是將輸入的字元串反轉過來。輸入字元串以字元數組 char[] 的形式給出。 不要給另外的數組分配額外的空間,你必須原地修改輸入數組、使用 O(1) 的額外空間解決這一問題。 你可以假設數組中的所有字元都是 ASCII 碼錶中的可列印字元。

示例 1: 輸入:["h","e","l","l","o"] 輸出:["o","l","l","e","h"]

解題思路:

利用首尾指針,然後向中間走,走的同時交換兩個位置的值!本來是用C++只需要三行程式碼,但凸顯不了我們的示例,因此使用異或來取代swap函數!這個之前題目有說到過!

class Solution {  public:      void reverseString(vector<char>& s) {          int l = 0, r = s.size()-1;          while(l < r){              //swap(s[l++], s[r--]);              s[l] ^= s[r];              s[r] ^= s[l];              s[l] ^= s[r];              l++, r--;          }      }  };

來源:力扣(LeetCode) 鏈接:https://leetcode-cn.com/problems/reverse-string

【LeetCode #345】反轉字元串的母音字母

編寫一個函數,以字元串作為輸入,反轉該字元串中的母音字母。

示例 1: 輸入: "hello" 輸出: "holle"

解題思路:

依然是雙指針(首尾指針)的方法,當不滿足母音時,則跳過,如果滿足,則交換兩個值。判斷一個字元是否為母音,這裡使用了哈希表!但其實使用string中的find函數更加高效一些!

class Solution {  public:      string reverseVowels(string s) {          int chares[] = {'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'};  //也可以使用string.find          unordered_set<char> set(chares, chares+10);          int l = 0, r = s.size()-1;          while(l < r){              if(set.find(s[l]) == set.end()){                  l++;              }else if(set.find(s[r]) == set.end()){                  r--;              }else{                  //swap(s[l++], s[r--]);                  s[l] ^= s[r];                  s[r] ^= s[l];                  s[l] ^= s[r];                  l++, r--;              }          }          return s;      }  };

來源:力扣(LeetCode) 鏈接:https://leetcode-cn.com/problems/reverse-vowels-of-a-string/

【LeetCode #347】前K個高頻元素

給定一個非空的整數數組,返回其中出現頻率前 k 高的元素。

示例 1: 輸入: nums = [1,1,1,2,2,3], k = 2 輸出: [1,2]

解題思路:

map按照value大小排序,由於map是關聯容器,本身就是有序的,但是按照key來排序的,這個之前也說過,map的迭代器是雙向迭代器,而sort函數只支援隨機訪問迭代器,因此需要拷貝到vector中進行排序處理! 滿滿的套路呀,之前就遇到過這種的!

class Solution {  public:      vector<int> topKFrequent(vector<int>& nums, int k) {          vector<int> res;          map<int, int> m;          for(auto num: nums){              m[num]++;          }          vector<pair<int, int>> vec(m.begin(), m.end());          sort(vec.begin(), vec.end(), [](pair<int, int>& a, pair<int, int>& b){              return a.second > b.second;          });          int i = 0;          while(i < k){              res.push_back(vec[i++].first);          }          return res;      }  };

來源:力扣(LeetCode) 鏈接:https://leetcode-cn.com/problems/top-k-frequent-elements/

【LeetCode #349】兩個數組的交集

給定兩個數組,編寫一個函數來計算它們的交集。

示例 1: 輸入: nums1 = [1,2,2,1], nums2 = [2,2] 輸出: [2]

解題思路:

直接使用STL演算法中的set操作函數,注意set有關的函數必須在排序序列中使用,因此必須先排序!然後使用unique函數去重即可!

(STL庫函數版本)

class Solution {  public:      vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {          vector<int> res;          sort(nums1.begin(), nums1.end());          sort(nums2.begin(), nums2.end());          set_intersection(nums1.begin(), nums1.end(), nums2.begin(), nums2.end(), back_inserter(res));          auto it = unique(res.begin(), res.end());          res.erase(it, res.end());          return res;      }  };

(非庫函數版本)

class Solution {  public:      vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {          vector<int> res;          for(int i = 0; i < nums1.size(); i ++){              for(int j = 0; j < nums2.size(); j++){                  if(nums1[i] == nums2[j]){                      res.push_back(nums1[i]);                      break;                  }              }          }          sort(res.begin(), res.end());          auto it = unique(res.begin(), res.end());          res.erase(it, res.end());          return res;      }  };

來源:力扣(LeetCode) 鏈接:https://leetcode-cn.com/problems/intersection-of-two-arrays/

【LeetCode #350】兩個數組的交集 II

給定兩個數組,編寫一個函數來計算它們的交集。

示例 1: 輸入: nums1 = [1,2,2,1], nums2 = [2,2] 輸出: [2,2]

解題思路:

相比於上一道題,簡單了,不用最後的去重了,太easy了,無力吐槽了!講道理不應該更難么?

在非庫函數版本中,我們可以使用映射map的方法,統計nums1中元素的個數,如果再nums2中出現,則減1,並將目標元素壓入res中!

(庫函數版本)

 vector<int> res;          sort(nums1.begin(), nums1.end());          sort(nums2.begin(), nums2.end());          set_intersection(nums1.begin(), nums1.end(), nums2.begin(), nums2.end(), back_inserter(res));          auto it = unique(res.begin(), res.end());          res.erase(it, res.end());          return res;

(非庫函數版本)

class Solution {  public:      vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {          map<int, int> m;          vector<int> res;          for(auto i: nums1){              m[i]++;          }          for(auto i: nums2){              if(m[i] != 0){                  m[i]--;                  res.push_back(i);              }          }          return res;      }  };

來源:力扣(LeetCode)

Tags: