剑指Offer II --- 2021/9/2

本文介绍了多种算法在实际问题中的应用,包括并查集解决朋友圈问题,二分查找实现快速定位,链表合并与排序,数组中的唯一数字查找,以及二进制加法。此外,还涉及全排列、组合与二进制运算的实际案例,展示了算法在信息技术领域的实用价值。
摘要由CSDN通过智能技术生成

剑指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. 合并排序链表

合并K个升序链表

剑指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 大的数字

数组中的第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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cyril_KI

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值