LeetCode:365 水壶问题 bfs+哈希set

有两个容量分别为 x升 和 y升 的水壶以及无限多的水。请判断能否通过使用这两个水壶,从而可以得到恰好 z升 的水?

如果可以,最后请用以上水壶中的一或两个来盛放取得的 z升 水。

你允许:

  • 装满任意一个水壶
  • 清空任意一个水壶
  • 从一个水壶向另外一个水壶倒水,直到装满或者倒空

示例 1: (From the famous “Die Hard” example)
输入: x = 3, y = 5, z = 4
输出: True

示例 2:
输入: x = 2, y = 6, z = 5
输出: False

来源

思路

可以dfs或bfs,不过因为操作步数确定,bfs显然更好

对于桶中水量,有6种可能的操作,用pair<int,int>保存状态,用哈希set记录访问的状态,然后直接bfs即可

  1. 把x桶装满
  2. 把y桶装满
  3. 把x桶倒空
  4. 把y桶倒空
  5. 把x桶的水倒入y直到x空或y满
  6. 把y桶的水倒入x直到y空或x满

借助队列实现bfs不难,关键是如何对重复的(x, y)二元组标识访问?

定义哈希set,存储的元素是pair<int,int>

这就要求对pair<int,int>实现哈希函数,(pair的比较函数已经自带了)

关于如何改写哈希

代码

这里使用的是层次遍历模板的bfs,方便求出操作次数

class Solution {
public:
    bool canMeasureWater(int x, int y, int z)
    {
        if(z==0 || z==x+y) return true;
        if(z>x+y) return false;
        struct hashfunc
        {
            size_t operator() (const pair<int,int> p) const
            {
                return size_t(p.first)*1000000007+p.second;
            }
        };
        unordered_set<pair<int,int>, hashfunc> hash;
        deque<pair<int,int>> q;
        q.push_back(pair<int,int>(0, 0)); hash.insert(pair<int,int>(0,0));
        while(!q.empty())
        {
            int qs = q.size();
            for(int i=0; i<qs; i++)
            {
                pair<int,int> tp=q.front(), next; q.pop_front();
                int X=tp.first, Y=tp.second;
                if(X+Y==z) return true;

                next = pair<int,int>(x, Y);
                if(hash.find(next)==hash.end())
                    hash.insert(next), q.push_back(next);
                next = pair<int,int>(X, y);
                if(hash.find(next)==hash.end())
                    hash.insert(next), q.push_back(next);
                next = pair<int,int>(0, Y);
                if(hash.find(next)==hash.end())
                    hash.insert(next), q.push_back(next);
                next = pair<int,int>(X, 0);
                if(hash.find(next)==hash.end())
                    hash.insert(next), q.push_back(next);
                
                int x_=(X+Y>=x)?(x):(X+Y), ry=(X+Y>=x)?(x-X):(0);
                int y_=(X+Y>=y)?(y):(X+Y), rx=(X+Y>=y)?(y-Y):(0);
                next = pair<int,int>(x_, ry);
                if(hash.find(next)==hash.end())
                    hash.insert(next), q.push_back(next);
                next = pair<int,int>(rx, y_);
                if(hash.find(next)==hash.end())
                    hash.insert(next), q.push_back(next);
            }
        }
        return false;
    }
};
发布了238 篇原创文章 · 获赞 7 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44176696/article/details/105012859