LeetCode第45场双周赛-解题报告
生活随笔
收集整理的這篇文章主要介紹了
LeetCode第45场双周赛-解题报告
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
LeetCode第45場雙周賽-解題報告
A. 唯一元素的和
原題鏈接
https://leetcode-cn.com/problems/sum-of-unique-elements/
解題思路
因為數據范圍比較小,可以直接模擬,如果出現一次就加上去。
或者是直接map打表也可以
AC代碼
暴力
class Solution { public:bool Check(int x, vector<int> &nums){int cnt = 0;for (auto y : nums)if (x == y)cnt ++;return cnt == 1;}int sumOfUnique(vector<int>& nums) {int ret = 0;for (auto x : nums){if (Check(x, nums))ret += x;}return ret;} };打表
class Solution { public:int sumOfUnique(vector<int>& nums) {int ans = 0;unordered_map<int, int> m;for (auto x : nums)m[x] ++;for (auto [u, v] : m) // 注意這個用法if (v == 1)ans += u;return ans;} };B. 任意子數組和的絕對值的最大值
原題鏈接
https://leetcode-cn.com/problems/maximum-absolute-sum-of-any-subarray/
解題思路
- 解題主要從子串入手,求得的是區間和的絕對值,那么很可能會用到前綴和。
- 進一步分析以RiR_iRi?為結尾子數組和絕對值最大時,LiL_iLi?會有什么性質,max(abs(PreSumRi?PreSumLi?1))max(abs(PreSum_{R_i}- PreSum_{L_i-1}))max(abs(PreSumRi???PreSumLi??1?)), PreSumRiPreSum_{R_i}PreSumRi??是確定的,根據絕對值的性質,可知,最大值取出在PreSumLi?1PreSum_{L_i-1}PreSumLi??1?在PreSumRiPreSum_{R_i}PreSumRi??左側最小,或PreSumRiPreSum_{R_i}PreSumRi??右側最大,那么我直接保留出PreMax,PreMinPreMax,PreMinPreMax,PreMin就可以線性處理出問題。
AC代碼
class Solution { public:int maxAbsoluteSum(vector<int>& nums) {int n = nums.size();vector<int> pre(n + 5);pre[0] = 0;for (int i = 1; i <= n; i ++ ) pre[i] = pre[i - 1] + nums[i - 1];int pre_max = 0, pre_min = 0;int res = 0;for (int i = 1; i <= n; i ++ ) // 對于右端點進行枚舉{pre_max = max(pre_max, pre[i]); pre_min = min(pre_min, pre[i]);res = max(res, max(abs(pre[i] - pre_max), abs(pre[i] - pre_min)));}return res;} };C. 刪除字符串兩端相同字符后的最短長度
原題鏈接
https://leetcode-cn.com/problems/minimum-length-of-string-after-deleting-similar-ends/
解題思路
- 1.當兩端字符不相同時,無法再次縮短
- 2.當兩端字符相同時,那么一定會取完
-
- 倘若一次尚未全部取完,那么可能會導致左右兩側字符不等,形成1.的局面
AC代碼
class Solution { public:int minimumLength(string s) {int pre = 0, nxt = s.size() - 1;char ch;while (s[pre] == s[nxt] && pre < nxt) // 倘若只剩最后一個,是不行的{ch = s[pre];while (s[pre] == ch && pre <= nxt) pre ++; // 注意是可以等于的while (s[nxt] == ch && pre <= nxt) nxt --;}return nxt - pre + 1;} };D. 最多可以參加的會議數目 II
原題鏈接
https://leetcode-cn.com/problems/maximum-number-of-events-that-can-be-attended-ii/
解題思路
倘若所有會議價值相同,僅僅有區間沖突,那么這就是一個貪心問題
只進行右端點排序,然后進行線性掃一遍數組,能加則加,因為我們是取最大數量的同時,使得結束時間盡可能的早。
當價值不同是,那么這是一個dp問題,思路類似于背包思路
AC代碼
const int N = 1000010; class Node { public:int st, ed, value;Node(int _st = 0, int _ed = 0, int _value = 0){st = _st, ed = _ed, value = _value;} }q[N]; bool cmp(const Node &t1, const Node &t2) {if (t1.ed == t2.ed)return t1.st < t2.st;elsereturn t1.ed < t2.ed; }class Solution { public:int maxValue(vector<vector<int>>& events, int k) {int n = events.size();for (int i = 0; i < n; i ++ )q[i + 1] = Node(events[i][0], events[i][1], events[i][2]);sort(q + 1, q + 1 + n, cmp); // 排序// vector<vector<int>(k + 5) > f(n + 5); // dp 數組vector<vector<int>> f(n + 5, vector<int>(k + 5));vector<int> pre(n + 5); // 預處理二分最近的不沖突區間pre[1] = 0; // 注意這個是0,而不是 - 1for (int i = 2; i <= n; i ++ ){static int l, r, mid, x;x = q[i].st;l = 1, r = i - 1;// q[mid].ed < x 的最大值if (q[1].ed >= x){pre[i] = 0;continue;}while (l < r){mid = (l + r + 1) >> 1;if (q[mid].ed < x)l = mid;elser = mid - 1;}pre[i] = l;}// 進行dp 初始化,按道理說沒有也是行的for (int i = 0; i <= k; i ++ )f[0][i] = 0;/*for (int i = 1; i <= n; i ++ )f[i][0] = 0, f[i][1] = max(q[i].value, f[i-1][1]); // 這個地方容易寫錯,不如在下面初始化*/for (int i = 1; i <= n; i ++ ){for (int j = 1; j <= k; j ++ ){f[i][j] = f[i - 1][j]; // 不選 i /// if (pre[i] == -1) continue;f[i][j] = max(f[i][j], f[pre[i]][j - 1] + q[i].value); // 選了 i }} return f[n][k];} };心得
- auto [u, v] : m 很好使,簡潔高效
- 處理子串(連續的)問題時,常常需要預處理區間,然后進行貪心,類似dp求解
- vector<vector> f(n + 5, vector(k + 5)); 有趣的寫法
總結
以上是生活随笔為你收集整理的LeetCode第45场双周赛-解题报告的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php获取当前世界,php获取网站ale
- 下一篇: 生活中c语言排序案例,C语言之数字排序-