【每日一题】886. 可能的二分法 2022/10/16

题目

886. 可能的二分法

思路

这种谁和谁一组,最后又要求是否能分组的问题,一眼并查集,但本题与最基础的并查集把同一种类的集合起来不同,他是把两种不同种类(互斥)的集合起来,其中的思想大概就是敌人的敌人就是朋友,这种并查集又称种类并查集。

并查集最基础的两个组件一个是find,一个是union。前者是找到当前元素所在集合的代表元素,给个比喻就是找到这个组员的组长,后者是合并,将两个组合并,实现方法就是将一个组的组长的组长变成另一个组的组长(原本每个组的组长都是他自己)。其中f[a]中储存的就是a的组长,在最开始每个成员的组长都是他自己。

int find(int a) {
    if(f[a] == a) return a;
    return f[a] = find(f[a]);
}
void uni(int a, int b) {
    f[find(a)] = find(f[b]);
}

基础的并查集就是每次读入两个人,将两个人合并。最后要查找某两个人是否有关系(find[a] = find[b]),然后给出答案。

该题中我们每次读入两个人后,就不能直接将两个人合并,而是分别将本人a与敌人b,本人b与敌人a合并,如果发现本人a与本人b有相同的敌人,那么就不可能将人分成两组,返回false。实现这样的功能我们就需要两倍n大的f数组。

代码如下

class Solution {
public:
    int f[4002];

    bool possibleBipartition(int n, vector<vector<int>>& dislikes) {
        
        for(int i = 0; i < n*2; i ++) {
            f[i] = i;
        }
        
        for(int i = 0; i < dislikes.size(); i ++) {

            //是否有共同的敌人
            if(find(dislikes[i][0]) == find(dislikes[i][1])) {
                return false;
            }

            //将本人与敌人结合
            uni(dislikes[i][0], dislikes[i][1] + n);
            uni(dislikes[i][0] + n, dislikes[i][1]);
        }

        return true;
    }

    int find(int a) {
        if(f[a] == a) return a;
        return f[a] = find(f[a]);
    }

    void uni(int a, int b) {
        f[find(a)] = find(f[b]);
    }
};

结果

总结

这是一道很模板的种类并查集,可以算是让我复习了相关的概念和实现方法。当然这题也可以使用搜索的方法来解决,思路会相对简单,但结果效率上应该就没并查集这么优秀了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要使用二分法解方程 x^3 + 5x + 7 = 0,我们需要定义一个函数来计算方程的值,并在给定的区间内应用二分法来找到方程的根。 首先,我们定义一个函数 `equation`,该函数接受一个参数 `x`,并返回方程的值: ```python def equation(x): return x**3 + 5*x + 7 ``` 接下来,我们可以实现二分法来逼近方程的根。二分法需要一个左边界 `left` 和一个右边界 `right`,并在这个区间内进行迭代,直到找到方程的根。 ```python def binary_search(left, right): while left <= right: mid = (left + right) / 2 # 计算中间值 value = equation(mid) # 计算方程的值 if abs(value) < 0.0001: # 当方程值足够接近于零时,认为找到了根 return mid if value > 0: # 方程值大于零,根在左侧 right = mid - 0.0001 else: # 方程值小于零,根在右侧 left = mid + 0.0001 return None # 没有找到根 ``` 在上述代码中,我们使用 `mid` 计算中间值,然后通过调用 `equation` 函数计算方程的值。如果方程的值接近于零,则返回中间值作为根。如果方程的值大于零,则更新右边界 `right`,将其设为中间值减去一个小的偏移量。如果方程的值小于零,则更新左边界 `left`,将其设为中间值加上一个小的偏移量。通过不断缩小区间,我们最终可以找到方程的根。 接下来,我们可以调用 `binary_search` 函数来解方程: ```python left = -10 # 左边界 right = 10 # 右边界 root = binary_search(left, right) if root is not None: print("方程的根为:", root) else: print("未找到方程的根") ``` 在上述示例中,我们将左边界 `left` 设置为 -10,右边界 `right` 设置为 10。然后,通过调用 `binary_search` 函数来解方程,并打印出根的值。 请注意,二分法可能不会找到方程的根,特别是当方程没有实根或有多个根的情况下。因此,在实际应用中,你可能需要考虑设置合适的边界和迭代次数来确保找到方程的根。 希望以上解释对你有帮助!如果还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

今夜大疯小宇

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

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

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

打赏作者

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

抵扣说明:

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

余额充值