查找表问题(c++)
来源:互联网 发布:java函数调用关系图 编辑:程序博客网 时间:2024/05/21 06:37
分类
查找有无
查找’a’是否存在?使用集合:set,unordered_set查找对应关系(键值对应)
元素’a’出现了几次?使用字典:map,unordered_map
set & map基本用法
- insert
- find
- erase
- change (map)
举例说明(LeetCode)
349. Intersection of Two Arrays
求两个集合的交集元素,相同元素只记录一次。
#include <iostream>#include <vector>#include <unordered_set>using namespace std;// 求两个集合的交集vector<int> intersection(vector<int>& nums1, vector<int>& nums2) { unordered_set<int> record(nums1.begin(), nums1.end()); unordered_set<int> ret; for (int i = 0; i < nums2.size(); i++){ if (record.find(nums2[i]) != record.end()){ ret.insert(nums2[i]); } } return vector<int>(ret.begin(), ret.end());}
350. Intersection of Two Arrays II
求两个集合的交集元素,相同元素需要记录次数。
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) { unordered_map<int, int> record; for (vector<int>::size_type i = 0; i < nums1.size(); i++){ record[nums1[i]]++; } vector<int> resultVec; for (vector<int>::size_type i = 0; i < nums2.size(); i++){ if (record[nums2[i]]>0){ resultVec.push_back(nums2[i]); record[nums2[i]]--; } } return resultVec;}
202. Happy Number
Write an algorithm to determine if a number is “happy”.
A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers.
Example: 19 is a happy number
1^2 + 9^2 = 828^2 + 2^2 = 686^2 + 8^2 = 1001^2 + 0^2 + 0^2 = 1
经过上面的循环,能得到1的就是happy number,否则就不是,什么情况下不是呢?实际上是算出的结果在前面已经出现,也就是循环了,这是明显查找有无的问题。
class Solution {public: bool isHappy(int n) { unordered_set<int> record; while (n != 1){ if (record.find(n) != record.end()) return false; else record.insert(n); int sum = 0; while (n != 0){ sum += pow(n % 10, 2); n /= 10; } n = sum; } // n==1 退出while,happy num return true; }};
290. Word Pattern
点击这里看问题描述,这是一个双向查找问题,不能只从一个方向到另一个方向,两者是11对应的,因此这类问题需要建立两个字典进行验证,正/反向查找。
输入输出示例:
pattern = "abba", str = "dog cat cat dog" should return true.pattern = "abba", str = "dog cat cat fish" should return false.pattern = "aaaa", str = "dog cat cat dog" should return false.pattern = "abba", str = "dog dog dog dog" should return false.
编码如下:
#include <iostream>#include <string>#include <sstream>#include <vector>#include <unordered_map>using namespace std;bool wordPattern(string pattern, string str) { stringstream ss(str); vector<string> vec; string temp; unordered_map<char, string> table_to; unordered_map<string, char> table_from; while (ss >> temp){ vec.push_back(temp); } if (pattern.size() != vec.size())return false; for (int i = 0; i < vec.size(); i++){ // 两个方向都有 if (table_to.find(pattern[i]) != table_to.end() && table_from.find(vec[i]) != table_from.end()){ if (table_to[pattern[i]] == vec[i] && table_from[vec[i]] == pattern[i]) continue; else return false; } // 两个方向都没有 else if (table_to.find(pattern[i]) == table_to.end() && table_from.find(vec[i]) == table_from.end()){ table_to.insert(make_pair(pattern[i], vec[i])); table_from.insert(make_pair(vec[i], pattern[i])); } else{ return false; } } return true;}
对上述问题进行优化
上述问题求解,虽然思路比较清晰,但代码编写起来比较繁琐,有时候为了表示两个方向的一一对应关系,不一定就需要用对方作为自己映射过去的值,我们可以用一个统一的索引来表示这种一一对应关系,比如我们可以将两个方向的值都对应为他们所在的位置索引。优化后,我们可以写出如下的代码:
bool wordPattern(string pattern, string str) { stringstream ss(str); vector<string> vec; string temp; while (ss >> temp){ vec.push_back(temp); } if (pattern.size() != vec.size())return false; unordered_map<char, int> p2w; unordered_map<string, int> w2p; for (int i = 0; i < vec.size(); i++){ if (p2w[pattern[i]] != w2p[vec[i]]) // 是否在同一位置,刚开始都为0 return false; p2w[pattern[i]] = w2p[vec[i]] = i + 1; //更新他们的标识,用i+1唯一标识 } return true;}
以上代码变得更加优雅,用i+1这个位置作为唯一标识,显得非常巧妙。
205. Isomorphic Strings
Given two strings s and t, determine if they are isomorphic.
Two strings are isomorphic if the characters in s can be replaced to get t.
All occurrences of a character must be replaced with another character while preserving the order of characters. No two characters may map to the same character but a character may map to itself.
For example,
Given "egg", "add", return true.Given "foo", "bar", return false.Given "paper", "title", return true.
同样,leetcode205号问题,也可以采用这个思路:
#include <iostream>#include <string>#include <unordered_map>using namespace std;bool isIsomorphic(string s, string t) { if (s.size() != t.size())return false; unordered_map<char, int> s2t, t2s; for (int i = 0; i < s.size(); i++){ if (s2t[s[i]] != t2s[t[i]])return false; s2t[s[i]] = t2s[t[i]] = i + 1; } return true;}
451. Sort Characters By Frequency
按照频率排列字符串。
1.Two Sum
class Solution {public: vector<int> twoSum(vector<int>& nums, int target) { unordered_map<int,int> record; for( int i = 0 ; i < nums.size() ; i ++ ){ int complement = target - nums[i]; if( record.find(complement) != record.end() ){ int res[] = {i, record[complement]}; return vector<int>(res, res + 2); } record[nums[i]] = i; } throw invalid_argument("the input has no solution"); }};
- 查找表问题(c++)
- 问题 C: 查找学生信息
- 连通性问题的快速查找解决方案(C语言实现)
- 【C/C++】折半查找(二分查找)
- 二分法查找(C)
- 二分查找(c)
- 二分查找(c & c++)
- 顺序表查找(顺序查找、二分查找) C语言实现
- c语言中#include 路径查找问题
- 线性查找,二分查找(C语言版)
- C语言 折半查找(二分查找)
- c/c++折半查找(二分查找)
- 查找(问题代码)
- 索引查找(索引查找、分块查找) C语言实现
- 算法 - 顺序查找(C#)
- 算法 - 折半查找(C#)
- C语言的库文件查找次序就是include问题(12)
- opencv(C++)扫描图像,查找表和时间测量
- java面试题:数组的常用算法实现
- 明白了一句话:“加速度信号对高频敏感,位移信号对低频敏感”
- Bigtable: A Distributed Storage System for Structured Data : part7 Performance Evaluation
- 方法递归调用
- 软件架构的一些心得
- 查找表问题(c++)
- 研判个股几个重要的维度
- WPF界面设计知识点整理
- ElasticSearch学习笔记-同义词记录
- 使用lombok写更简洁的Java代码
- DevOps落地问题
- mysql-触发器
- js中的new image()
- 【狼人杀】初阶教学——基本规则