目录
剑指Offer II 116. 朋友圈
分析:
并查集,参考:并查集的介绍及简单应用—蓝桥杯真题:合根植物
代码:
class Solution {
private:
int get_root(int x) {
if(fa[x] != x) {
fa[x] = get_root(fa[x]);
}
return fa[x];
}
void merge(int a, int b) {
fa[get_root(a)] = get_root(b);
}
bool query(int a, int b) {
return get_root(a) == get_root(b);
}
public:
vector<int> fa;
int findCircleNum(vector<vector<int>>& isConnected) {
int n = isConnected.size();
fa = vector<int>(n);
for(int i = 0; i < n; i++) {
fa[i] = i;
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
if(isConnected[i][j]) {
merge(i, j);
}
}
}
set<int> s;
for(int i = 0; i < n; i++) {
s.insert(get_root(i));
}
return s.size();
}
};
剑指Offer II 098. 路径的数目
剑指Offer II 068. 查找插入位置
分析:
要求O(logn),所以使用二分查找。
代码:
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int low = 0, high = nums.size() - 1;
while(low <= high) {
int mid = low + (high - low) / 2;
if(target > nums[mid]) {
low = mid + 1;
}else if(target < nums[mid]) {
high = mid - 1;
}else {
return mid;
}
}
return low;
}
};
剑指Offer II 078. 合并排序链表
剑指Offer II 066. 单词之和
分析:
遍历判断是否满足条件再相加。
代码:
class MapSum {
public:
/** Initialize your data structure here. */
unordered_map<string, int> mp;
MapSum() {
}
void insert(string key, int val) {
mp[key] = val;
}
int sum(string prefix) {
int res = 0, n = prefix.size();
for(auto& [x, y] : mp) {
if(x.size() >= n && x.substr(0, n) == prefix) {
res += y;
}
}
return res;
}
};
/**
* Your MapSum object will be instantiated and called as such:
* MapSum* obj = new MapSum();
* obj->insert(key,val);
* int param_2 = obj->sum(prefix);
*/
剑指Offer II 070. 排序数组中只出现一次的数字
方法一:
异或运算。
代码:
class Solution {
public:
int singleNonDuplicate(vector<int>& nums) {
int ret = 0;
for(int x : nums) {
ret ^= x;
}
return ret;
}
};
方法二:
二分法:将所有数字两两分组,比如112334488分为11 23 34 48 8,然后二分查找某一个组,如果该组的两个数不相等但其前面一组两个数相等就返回。
代码:
class Solution {
public:
int singleNonDuplicate(vector<int>& nums) {
int left = 0;
int right = nums.size() / 2 - 1;
while (left <= right) {
int mid = left + ((right - left) >> 1);
int i = 2 * mid;
if (nums[i] != nums[i + 1]) {
if (i == 0 || nums[i - 1] == nums[i - 2]) {
return nums[i];
}
right = mid - 1;
}
else {
left = mid + 1;
}
}
return nums.back();
}
};
剑指Offer II 076. 数组中的第 k 大的数字
剑指Offer II 080. 含有 k 个元素的组合
剑指Offer II 002. 二进制加法
分析:
从尾开始模拟二进制加法。
代码:
class Solution {
public:
string addBinary(string a, string b) {
string res = "";
int n = a.size(), m = b.size();
int i = n - 1, j = m - 1, cnt = 0;
while(i >= 0 || j >= 0) {
int x, y;
if(i < 0) {
x = 0;
}else {
stringstream ss;
ss << a[i];
ss >> x;
}
if(j < 0) {
y = 0;
}else {
stringstream ss;
ss << b[j];
ss >> y;
}
int sum = x + y + cnt;
// cout << sum << endl;
cnt = sum / 2;
res += to_string(sum % 2);
i--;
j--;
}
if(cnt != 0) {
res += to_string(cnt);
}
reverse(res.begin(), res.end());
return res;
}
};
剑指Offer II 084. 含有重复元素集合的全排列
分析:
c++的next_permutation()。
代码:
class Solution {
public:
vector<vector<int>> permuteUnique(vector<int>& nums) {
vector<vector<int>> res;
sort(nums.begin(), nums.end());
do {
res.push_back(nums);
}while(next_permutation(nums.begin(), nums.end()));
return res;
}
};