给定两个数组,编写一个函数来计算它们的交集。
1 class Solution { 2 public: 3 vector<int> intersection(vector<int>& nums1, vector<int>& nums2) { 4 unordered_set<int> result_set; // 存放结果,之所以用set是为了给结果集去重 5 unordered_set<int> nums_set(nums1.begin(), nums1.end()); 6 for (int num : nums2) { 7 // 发现nums2的元素 在nums_set里又出现过 8 if (nums_set.find(num) != nums_set.end()) { 9 result_set.insert(num); 10 } 11 } 12 return vector<int>(result_set.begin(), result_set.end()); 13 } 14 };
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为 1,那么这个数就是快乐数。
如果 n 是快乐数就返回 True ;不是,则返回 False 。
示例:
输入:19
输出:true
解释:
1^2 + 9^2 = 82
8^2 + 2^2 = 68
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 1
#思路
这道题目看上去貌似一道数学问题,其实并不是!
题目中说了会 无限循环,那么也就是说求和的过程中,sum会重复出现,这对解题很重要!
正如:关于哈希表,你该了解这些! (opens new window)中所说,当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法了。
所以这道题目使用哈希法,来判断这个sum是否重复出现,如果重复了就是return false, 否则一直找到sum为1为止。
判断sum是否重复出现就可以使用unordered_set。
还有一个难点就是求和的过程,如果对取数值各个位上的单数操作不熟悉的话,做这道题也会比较艰难。
1 bool isHappy(int n) { 2 unordered_set<int> set; 3 while(1) { 4 int sum = getSum(n); 5 if (sum == 1) { 6 return true; 7 } 8 // 如果这个sum曾经出现过,说明已经陷入了无限循环了,立刻return false 9 if (set.find(sum) != set.end()) { 10 return false; 11 } else { 12 set.insert(sum); 13 } 14 n = sum; 15 } 16 }
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回
1 vector<int> twoSum(vector<int>& nums, int target) { 2 std::unordered_map <int,int> map; 3 for(int i = 0; i < nums.size(); i++) { 4 // 遍历当前元素,并在map中寻找是否有匹配的key 5 auto iter = map.find(target - nums[i]); 6 if(iter != map.end()) { 7 return {iter->second, i}; 8 } 9 // 如果没找到匹配对,就把访问过的元素和下标加入到map中 10 map.insert(pair<int, int>(nums[i], i)); 11 } 12 return {}; 13 }
给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0。
为了使问题简单化,所有的 A, B, C, D 具有相同的长度 N,且 0 ≤ N ≤ 500 。所有整数的范围在 -2^28 到 2^28 - 1 之间,最终结果不会超过 2^31 - 1 。
例如:
输入:
A = [ 1, 2]
B = [-2,-1]
C = [-1, 2]
D = [ 0, 2]
输出:
2
1 int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) { 2 unordered_map<int, int> umap; //key:a+b的数值,value:a+b数值出现的次数 3 // 遍历大A和大B数组,统计两个数组元素之和,和出现的次数,放到map中 4 for (int a : A) { 5 for (int b : B) { 6 umap[a + b]++; 7 } 8 } 9 int count = 0; // 统计a+b+c+d = 0 出现的次数 10 // 在遍历大C和大D数组,找到如果 0-(c+d) 在map中出现过的话,就把map中key对应的value也就是出现次数统计出来。 11 for (int c : C) { 12 for (int d : D) { 13 if (umap.find(0 - (c + d)) != umap.end()) { 14 count += umap[0 - (c + d)]; 15 } 16 } 17 } 18 return count; 19 }
给定一个赎金信 (ransom) 字符串和一个杂志(magazine)字符串,判断第一个字符串 ransom 能不能由第二个字符串 magazines 里面的字符构成。如果可以构成,返回 true ;否则返回 false。
(题目说明:为了不暴露赎金信字迹,要从杂志上搜索各个需要的字母,组成单词来表达意思。杂志字符串中的每个字符只能在赎金信字符串中使用一次。)
注意:
你可以假设两个字符串均只含有小写字母。
canConstruct("a", "b") -> false
canConstruct("aa", "ab") -> false
1 bool canConstruct(string ransomNote, string magazine) { 2 int record[26] = {0}; 3 //add 4 if (ransomNote.size() > magazine.size()) { 5 return false; 6 } 7 for (int i = 0; i < magazine.length(); i++) { 8 // 通过record数据记录 magazine里各个字符出现次数 9 record[magazine[i]-'a'] ++; 10 } 11 for (int j = 0; j < ransomNote.length(); j++) { 12 // 遍历ransomNote,在record里对应的字符个数做--操作 13 record[ransomNote[j]-'a']--; 14 // 如果小于零说明ransomNote里出现的字符,magazine没有 15 if(record[ransomNote[j]-'a'] < 0) { 16 return false; 17 } 18 } 19 return true; 20 }
标签:map,set,return,nums,int,vector,哈希,使用,一些 From: https://www.cnblogs.com/saucerdish/p/17822481.html