1. 程式人生 > 其它 >LeetCode第 285 場周賽題解

LeetCode第 285 場周賽題解

6027. 統計陣列中峰和谷的數量

題目描述:給你一個數組nums,統計山峰和山谷的數量,山峰山谷的定義見題目

思路:資料範圍不大,根據題意暴力模擬即可,若資料範圍很大,則將相鄰且相等的元素刪除其一,對於刪除後的陣列,可以\(O(n)\)求解

時間複雜度:\(O(n^2)\)

參考程式碼:

class Solution {
public:
    int countHillValley(vector<int>& nums) {
        int res = 0, n = nums.size();
        vector<int>vis(n + 1 , false);
        for(int i = 1 ; i < n - 1 ; ++i){
            int lr = -1;
            for(int j = i - 1 ; j >= 0 ;--j){
                if(nums[j] == nums[i]) continue;
                lr = nums[j];
                break;
            }
            if(lr == -1) continue;
            int rs = -1;
            for(int j = i + 1 ; j < n ; ++j){
                if(nums[j] == nums[i]) continue;
                rs = nums[j];
                break;
            }
            if(rs == -1) continue;
            if(lr > nums[i] && rs > nums[i]){
                ++res;
                vis[i] = true;
                if(vis[i - 1] == true && nums[i - 1] == nums[i]) --res;
            }
            else if(lr < nums[i] && rs < nums[i]){
                ++res;
                vis[i] = true;
                if(vis[i - 1] == true && nums[i - 1] == nums[i]) --res;
            }
        }
        return res;
    }
};

\(O(n)\)解法:

class Solution {
public:
    int countHillValley(vector<int>& nums) {
        deque<int>q;
        for(auto& num : nums){
            if(q.empty())q.push_back(num);
            else if(q.back() == num) continue;
            else q.push_back(num);
        }
        nums.clear();
        while(!q.empty()){
            nums.push_back(q.front());
            q.pop_front();
        }
        int res = 0 , n = nums.size();
        for(int i = 1 ; i < n - 1 ; ++i){
            if(nums[i] < nums[i - 1] && nums[i] < nums[i + 1]) ++res;
            if(nums[i] > nums[i - 1] && nums[i] > nums[i + 1]) ++res;
        }
        return res;
    }
};

6028. 統計道路上的碰撞次數

題目描述:給你一個長度為\(n\)的字串s表示n輛車的狀態,R表示向右行駛,L表示向左行駛,S表示不動。若兩輛相對行駛的車相撞積兩分,若一個行駛的車撞上了一個靜止的車積一分,兩輛車相撞之後就會保持靜止。問最終積分是多少。

思路:根據題意模擬即可

時間複雜度:\(O(n)\)

參考程式碼:

class Solution {
public:
    int countCollisions(string s) {
        int res = 0;
        int cntlr = 0 , cntrs = 0, stop = 0;
        for(auto& c : s){
            if(c == 'S'){
                res += cntrs;
                cntrs = 0;
                stop = 1;
            }
            else if(c == 'L'){
                if(cntrs){
                    res += cntrs + 1;
                    cntrs = 0;
                    stop = 1;
                }
                else if(stop) res++;
            }
            else ++cntrs;
        }
        return res;
    }
};

6029. 射箭比賽中的最大得分

題目描述:兩個人比賽射箭,假定這兩個人用AB表示,他們都射n支箭,靶總共有12個區域,分別表示0 , 1 , ... , 11分,對於同一分數區域,只有當B射在該區域的箭的數量多於A射在該區域的箭的數量時,B才可以獲得該區域所代表的分數,問B最多能獲得多少分。

思路:考慮到總共只有12個區域,所以我們列舉B勝利的區域,然後檢驗所用箭的數量是否超過閾值即可。注意B使用的箭的總數量與A使用的箭的總數量必須相等。

時間複雜度:\(O(12 * 2 ^{12})\)

參考程式碼:

class Solution {
public:
    vector<int> maximumBobPoints(int numArrows, vector<int>& a) {
        vector<bool>vis(12 , 0);
        vector<int>res;
        int mx = 0;
        auto dfs = [&](auto&& dfs , int cur)->void{
            if(cur == 12){
                int cnt = 0, sum = 0;
                vector<int>ans(12 , 0);
                for(int i = 0 ; i < 12 ; ++i){
                    if(vis[i] == false) continue;
                    ans[i] = a[i] + 1;
                    cnt += a[i] + 1;
                    sum += i;
                }
                if(cnt > numArrows) return ;
                if(sum <= mx) return ;
                ans[0] += numArrows - cnt;
                mx = sum;
                res = ans;
                return ;
            }
            dfs(dfs , cur + 1);
            vis[cur] = true;
            dfs(dfs , cur + 1);
            vis[cur] = false;
        };
        dfs(dfs , 0);
        return res;
    }
};

6030. 由單個字元重複的最長子字串

題目描述:給你一個長度為n的字串s,在給你q個詢問,每次詢問修改某處字元為給定字元,問每次修改後字串s中由單個字元重複組成的最長子字串的長度。

思路:比較明顯可以使用線段樹,維護最長字串。同時維護區間的字首最長,字尾最長,區間最長,最前面的數的值,最後面的數的值這5個資訊,然後單點修改即可,每次詢問的答案就是tree[1].mx

時間複雜度:\(O(nlogn + qlogn)\)

參考程式碼:

class Solution {
private:
	struct SegTree {
		int lr, rs, mid;
		int val, pre, nxt, mx, preval, nxtval;
	};
	vector<SegTree> tree;
	void pushUp(int rt) {
		tree[rt].mx = max(tree[rt << 1].mx, tree[rt << 1 | 1].mx);
		if (tree[rt << 1].nxtval == tree[rt << 1 | 1].preval) {
			int len = tree[rt << 1].nxt + tree[rt << 1 | 1].pre;
			tree[rt].mx = max(tree[rt].mx, len);
		}
		tree[rt].pre = tree[rt << 1].pre;
		tree[rt].nxt = tree[rt << 1 | 1].nxt;
		tree[rt].preval = tree[rt << 1].preval;
		tree[rt].nxtval = tree[rt << 1 | 1].nxtval;
		if (tree[rt].pre == tree[rt << 1].rs - tree[rt << 1].lr + 1) {
			if (tree[rt << 1].nxtval == tree[rt << 1 | 1].preval) tree[rt].pre += tree[rt << 1 | 1].pre;
			else;
		}
		if (tree[rt].nxt == tree[rt << 1 | 1].rs - tree[rt << 1 | 1].lr + 1) {
			if (tree[rt << 1].nxtval == tree[rt << 1 | 1].preval) tree[rt].nxt += tree[rt << 1].nxt;
			else;
		}
		return;
	}
	void buildTree(string& s, int rt, int lr, int rs) {
		tree[rt].lr = lr; tree[rt].rs = rs; tree[rt].mx = 0;
		if (lr == rs) {
			tree[rt].val = s[lr - 1] - 'a' + 1;
			tree[rt].mx = 1;
			tree[rt].preval = tree[rt].nxtval = tree[rt].val;
			tree[rt].pre = tree[rt].nxt = 1;
			return;
		}
		int mid = tree[rt].mid = lr + rs >> 1;
		buildTree(s, rt << 1, lr, mid);
		buildTree(s, rt << 1 | 1, mid + 1, rs);
		pushUp(rt);
		return;
	}
	void update(int rt, int pos , int val) {
		if (tree[rt].lr > pos || tree[rt].rs < pos) return;
		if (tree[rt].lr == tree[rt].rs) {
			tree[rt].val = val;
			tree[rt].preval = val;
			tree[rt].nxtval = val;
			return;
		}
		if (tree[rt].mid >= pos) update(rt << 1, pos, val);
		else update(rt << 1 | 1, pos, val);
		pushUp(rt);
		return;
	}
public:
	vector<int> longestRepeating(string s, string queryCharacters, vector<int>& queryIndices) {
		int n = s.size();
		tree = vector<SegTree>(n + 5 << 2);
		buildTree(s, 1, 1, n);
		int m = queryCharacters.size();
		vector<int>res(m , 0);
		for (int i = 0; i < m; ++i) {
			int pos = queryIndices[i] + 1, val = queryCharacters[i] - 'a' + 1;
			update(1, pos, val);
			res[i] = tree[1].mx;
		}
		return res;
	}
};