力扣周賽 1488. 避免洪水氾濫(min型線段樹)

你的國家有無數個湖泊,所有湖泊一開始都是空的。當第 n 個湖泊下雨的時候,如果第 n 個湖泊是空的,那麼它就會裝滿水,否則這個湖泊會發生洪水。你的目標是避免任意一個湖泊發生洪水。

給你一個整數數組 rains ,其中:

  • rains[i] > 0 表示第 i 天時,第 rains[i] 個湖泊會下雨。
  • rains[i] == 0 表示第 i 天沒有湖泊會下雨,你可以選擇 一個 湖泊並 抽乾 這個湖泊的水。

請返回一個數組 ans ,滿足:

  • ans.length == rains.length
  • 如果 rains[i] > 0 ,那麼ans[i] == -1 。
  • 如果 rains[i] == 0 ,ans[i] 是你第 i 天選擇抽乾的湖泊。

如果有多種可行解,請返回它們中的 任意一個 。如果沒辦法阻止洪水,請返回一個 空的數組 。

請注意,如果你選擇抽乾一個裝滿水的湖泊,它會變成一個空的湖泊。但如果你選擇抽乾一個空的湖泊,那麼將無事發生(詳情請看示例 4)。

 

示例 1:

輸入:rains = [1,2,3,4]
輸出:[-1,-1,-1,-1]
解釋:第一天後,裝滿水的湖泊包括 [1]
第二天後,裝滿水的湖泊包括 [1,2]
第三天後,裝滿水的湖泊包括 [1,2,3]
第四天後,裝滿水的湖泊包括 [1,2,3,4]
沒有哪一天你可以抽乾任何湖泊的水,也沒有湖泊會發生洪水。

示例 2:

輸入:rains = [1,2,0,0,2,1]
輸出:[-1,-1,2,1,-1,-1]
解釋:第一天後,裝滿水的湖泊包括 [1]
第二天後,裝滿水的湖泊包括 [1,2]
第三天後,我們抽乾湖泊 2 。所以剩下裝滿水的湖泊包括 [1]
第四天後,我們抽乾湖泊 1 。所以暫時沒有裝滿水的湖泊了。
第五天後,裝滿水的湖泊包括 [2]。
第六天後,裝滿水的湖泊包括 [1,2]。
可以看出,這個方案下不會有洪水發生。同時, [-1,-1,1,2,-1,-1] 也是另一個可行的沒有洪水的方案。

示例 3:

輸入:rains = [1,2,0,1,2]
輸出:[]
解釋:第二天後,裝滿水的湖泊包括 [1,2]。我們可以在第三天抽乾一個湖泊的水。
但第三天後,湖泊 1 和 2 都會再次下雨,所以不管我們第三天抽乾哪個湖泊的水,另一個湖泊都會發生洪水。

示例 4:

輸入:rains = [69,0,0,0,69]
輸出:[-1,69,1,1,-1]
解釋:任何形如 [-1,69,x,y,-1], [-1,x,69,y,-1] 或者 [-1,x,y,69,-1] 都是可行的解,其中 1 <= x,y <= 10^9

示例 5:

輸入:rains = [10,20,20]
輸出:[]
解釋:由於湖泊 20 會連續下 2 天的雨,所以沒有沒有辦法阻止洪水。

 

提示:

  • 1 <= rains.length <= 10^5
  • 0 <= rains[i] <= 10^9
int n,minn[400000];
vector<int>num;
 
void build(int key, int low, int high)
{
	if (low == high)
	{
		minn[key] = num[low];
		return;
	}
	int mid = (low + high) / 2;
	build(key * 2, low, mid);
	build(key * 2 + 1, mid + 1, high);
	minn[key] = (minn[key * 2] < minn[key * 2 + 1]) ? minn[key * 2] : minn[key * 2 + 1];
}
 
void update(int key, int low, int high, int uplace)
{
	if (low == high)
	{
		minn[key] = num[low];
		return;
	}
	int mid = (low + high) / 2;
	if (uplace <= mid)update(key * 2, low, mid, uplace);
	else update(key * 2 + 1, mid + 1, high, uplace);
	minn[key] = (minn[key * 2] < minn[key * 2 + 1]) ? minn[key * 2] : minn[key * 2 + 1];
}
 
int query(int key, int low, int high, int x, int y)
{
	if (low == x && high == y)return minn[key];
	int mid = (low + high) / 2;
	if (mid < x)return query(key * 2 + 1, mid + 1, high, x, y);
	if (mid >= y)return query(key * 2, low, mid, x, y);
	int a = query(key * 2, low, mid, x, mid);
	int b = query(key * 2 + 1, mid + 1, high, mid + 1, y);
	return  (a<b) ? a : b;
}
class Solution {
public:
vector<int> avoidFlood(vector<int>& rains) {
        num=rains;    
        num.insert(num.begin(),0);
        n=rains.size();
        for(int i=0;i<rains.size();i++)num[i+1]=(rains[i]==0)?i:1234567;
        build(1, 1, n);
        unordered_map<int,int>m;
        vector<int>ans,ansempty;
        ans.resize(n,1);
        for(int i=0;i<rains.size();i++)
        {            
            if(rains[i]==0)continue;
            if(m[rains[i]]==0)
            {
                m[rains[i]]=i+1;
                continue;
            }
            int k=m[rains[i]]-1;
            int km=query(1,1,n,k+1,i+1);
            if(km==1234567)return ansempty;
            num[km+1]=1234567;
            update(1,1,n,km+1);
            m[rains[i]]=i+1;
            ans[km]=rains[i];
        }
        for(int i=0;i<rains.size();i++)if(rains[i])ans[i]=-1;
        return ans;
    }
};

 

PS:

我掛的2個用例:

[0,1,1]
[2,3,0,0,3,1,0,1,0,2,2]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章