双指针,集合问题-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)