日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

LeetCode 第 186 场周赛(1060/3107,前34.1%)

發(fā)布時(shí)間:2024/7/5 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LeetCode 第 186 场周赛(1060/3107,前34.1%) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

    • 1. 比賽結(jié)果
    • 2. 題目
      • 1. LeetCode 5392. 分割字符串的最大得分 easy
      • 2. LeetCode 5393. 可獲得的最大點(diǎn)數(shù) medium
      • 3. LeetCode 5394. 對(duì)角線遍歷 II medium
      • 4. LeetCode 5180. 帶限制的子序列和 hard

1. 比賽結(jié)果

做出來了 1、2 題,第3題模擬法,超時(shí),第4題不會(huì),繼續(xù)加油!

全國(guó)排名:1060 / 3107,34.1%;全球排名:4145 / 11687,35.5%

2. 題目

1. LeetCode 5392. 分割字符串的最大得分 easy

題目鏈接

給你一個(gè)由若干 0 和 1 組成的字符串 s ,請(qǐng)你計(jì)算并返回將該字符串分割成兩個(gè) 非空 子字符串(即 左 子字符串和 右 子字符串)所能獲得的最大得分

「分割字符串的得分」為 子字符串中 0 的數(shù)量加上 子字符串中 1 的數(shù)量。

示例 1: 輸入:s = "011101" 輸出:5 解釋: 將字符串 s 劃分為兩個(gè)非空子字符串的可行方案有: 左子字符串 = "0" 且 右子字符串 = "11101",得分 = 1 + 4 = 5 左子字符串 = "01" 且 右子字符串 = "1101",得分 = 1 + 3 = 4 左子字符串 = "011" 且 右子字符串 = "101",得分 = 1 + 2 = 3 左子字符串 = "0111" 且 右子字符串 = "01",得分 = 1 + 1 = 2 左子字符串 = "01110" 且 右子字符串 = "1",得分 = 2 + 1 = 3示例 2: 輸入:s = "00111" 輸出:5 解釋:當(dāng) 左子字符串 = "00" 且 右子字符串 = "111" 時(shí), 我們得到最大得分 = 2 + 3 = 5示例 3: 輸入:s = "1111" 輸出:3提示: 2 <= s.length <= 500 字符串 s 僅由字符 '0''1' 組成。

解答:

  • 左右兩邊,前綴0,后綴1,一次遍歷即可

    比賽的時(shí)候?qū)懙挠悬c(diǎn)繁瑣
class Solution { public:int maxScore(string s) {vector<int> left0(2*s.size()-1,0);vector<int> right1(2*s.size()-1,0);int i, n = s.size();left0[0] = s[0]=='0' ? 1 : 0;for(i = 1; i < n; ++i)left0[2*i] = s[i]=='0'? left0[2*i-2]+1 : left0[2*i-2];right1[2*n-2] = s[n-1]=='1' ? 1 : 0;for(i = n-2; i >= 0; --i)right1[2*i] = s[i]=='1'? right1[2*i+2]+1 : right1[2*i+2];int maxsc = 0;for(i = 1; i < 2*n-2; i+=2)maxsc = max(maxsc, left0[i-1]+right1[i+1]);return maxsc;} };

4 ms 6.9 MB

賽后解

class Solution { public:int maxScore(string s) {int i, one = 0, maxs = 0, zero = 0;for(i = 0; i < s.size(); ++i){if(s[i]=='1')one++;}for(i = 0; i < s.size()-1; ++i){if(s[i]=='0')zero++;elseone--;maxs = max(maxs,zero+one);}return maxs;} };

0 ms 6.4 MB

2. LeetCode 5393. 可獲得的最大點(diǎn)數(shù) medium

題目鏈接
幾張卡牌 排成一行,每張卡牌都有一個(gè)對(duì)應(yīng)的點(diǎn)數(shù)。
點(diǎn)數(shù)由整數(shù)數(shù)組 cardPoints 給出。

每次行動(dòng),你可以從行的開頭或者末尾拿一張卡牌,最終你必須正好拿 k 張卡牌。

你的點(diǎn)數(shù)就是你拿到手中的所有卡牌的點(diǎn)數(shù)之和。

給你一個(gè)整數(shù)數(shù)組 cardPoints 和整數(shù) k,請(qǐng)你返回可以獲得的最大點(diǎn)數(shù)。

示例 1: 輸入:cardPoints = [1,2,3,4,5,6,1], k = 3 輸出:12 解釋:第一次行動(dòng),不管拿哪張牌,你的點(diǎn)數(shù)總是 1 。 但是,先拿最右邊的卡牌將會(huì)最大化你的可獲得點(diǎn)數(shù)。 最優(yōu)策略是拿右邊的三張牌,最終點(diǎn)數(shù)為 1 + 6 + 5 = 12 。示例 2: 輸入:cardPoints = [2,2,2], k = 2 輸出:4 解釋:無論你拿起哪兩張卡牌,可獲得的點(diǎn)數(shù)總是 4 。示例 3: 輸入:cardPoints = [9,7,7,9,7,7,9], k = 7 輸出:55 解釋:你必須拿起所有卡牌,可以獲得的點(diǎn)數(shù)為所有卡牌的點(diǎn)數(shù)之和。示例 4: 輸入:cardPoints = [1,1000,1], k = 1 輸出:1 解釋:你無法拿到中間那張卡牌,所以可以獲得的最大點(diǎn)數(shù)為 1 。 示例 5: 輸入:cardPoints = [1,79,80,1,1,1,200,1], k = 3 輸出:202提示: 1 <= cardPoints.length <= 10^5 1 <= cardPoints[i] <= 10^4 1 <= k <= cardPoints.length

解答:

比賽的時(shí)候差點(diǎn)被坑,以為是DP,一想左右各取a,b個(gè),a+b = k 不就完了嗎
(也可以反過來想,求中間子序和最小,滑動(dòng)窗口)

class Solution { public:int maxScore(vector<int>& cardPoints, int k) {vector<int> l(k+2,0);vector<int> r(k+2,0);int len = 1, i;for(i = 0; i < k; ++i,++len)l[len] = cardPoints[i]+l[len-1];len = 1;for(i = cardPoints.size()-1; len <= k; --i,++len)r[len] = cardPoints[i]+r[len-1];int maxScore = 0;for(len = 0; len <= k; ++len)maxScore = max(maxScore, l[len]+r[k-len]);return maxScore;} };

148 ms 44.2 MB

3. LeetCode 5394. 對(duì)角線遍歷 II medium

題目鏈接
給你一個(gè)列表 nums ,里面每一個(gè)元素都是一個(gè)整數(shù)列表。
請(qǐng)你依照下面各圖的規(guī)則,按順序返回 nums 中對(duì)角線上的整數(shù)。

示例 1:

輸入:nums = [[1,2,3],[4,5,6],[7,8,9]] 輸出:[1,4,2,7,5,3,8,6,9]

示例 2:

輸入:nums = [[1,2,3,4,5],[6,7],[8],[9,10,11],[12,13,14,15,16]] 輸出:[1,6,2,8,7,3,9,4,12,10,5,13,11,14,15,16]示例 3: 輸入:nums = [[1,2,3],[4],[5,6,7],[8],[9,10,11]] 輸出:[1,4,2,5,3,8,6,9,7,10,11]示例 4: 輸入:nums = [[1,2,3,4,5,6]] 輸出:[1,2,3,4,5,6]提示: 1 <= nums.length <= 10^5 1 <= nums[i].length <= 10^5 1 <= nums[i][j] <= 10^9 nums 中最多有 10^5 個(gè)數(shù)字。

比賽模擬寫法超時(shí):

class Solution { public:vector<int> findDiagonalOrder(vector<vector<int>>& nums) {vector<int> ans;int i = 0, j = 0, count = 0, c = 0, x, y, m = nums.size(),n=0, finishi = -1;vector<int> precount(nums.size(),0);for(i = 0; i < m; ++i){count += nums[i].size();//總個(gè)數(shù)n = max(n, int(nums[i].size()));//列最大個(gè)數(shù)}x = y = i = j = 0;while(c < count){i = x, j = y;//x,y起始位置while(i>=0 && j<n && c<count){if(j < nums[i].size())//在范圍內(nèi){ans.push_back(nums[i][j]);c++;//計(jì)數(shù)+1precount[i]++;//該行寫入答案數(shù)量+1if(precount[i]==nums[i].size())//這行寫完了{if(precount[finishi+1] == nums[finishi+1].size())finishi++;//檢查已完成的行,能不能往下挪}}i--;j++;if(i <= finishi)break;}x++;if(x >= m){x = m-1;y++;}}return ans;} };

賽后解1:(依然超時(shí))

實(shí)際上是按點(diǎn)的位置(r,c)排序:總的是r+c小的靠前,一樣的話,r 大的靠前。

class Solution { public:vector<int> findDiagonalOrder(vector<vector<int>>& nums) {int i, j;vector<vector<int>> v; //posx+posy, posx, valfor(i = 0; i < nums.size(); ++i){for(j = 0; j < nums[i].size(); ++j){v.push_back({i+j, i, nums[i][j]});}}sort(v.begin(), v.end(),[&](auto a, auto b){if(a[0]==b[0])return a[1] > b[1];return a[0] < b[0];});vector<int> ans(v.size());i = 0;for(auto& vi : v)ans[i++] = vi[2];return ans;} };

估計(jì)是排序時(shí)間復(fù)雜度還是太高。


賽后解2:

  • 按照兩個(gè)坐標(biāo)值的和分組,存入map,內(nèi)層再嵌套map(x,val)
  • 外層順序遍歷(坐標(biāo)和小的先),內(nèi)層逆序遍歷(x大的先)
class Solution { public:vector<int> findDiagonalOrder(vector<vector<int>>& nums) {int i, j, size = 0;map<int,map<int,int>> m;//posx+posy, posx, valfor(i = 0; i < nums.size(); ++i){for(j = 0; j < nums[i].size(); ++j){m[i+j][i] = nums[i][j];size++;}}vector<int> ans(size);i = 0;for(auto it = m.begin(); it != m.end(); ++it){for(auto it1 = it->second.rbegin(); it1 != it->second.rend(); ++it1)ans[i++] = it1->second;}return ans;} };


或者用數(shù)組做,參考lc題解,也是按坐標(biāo)和分組,每組里面逆序?qū)懭氪鸢浮?/p>

4. LeetCode 5180. 帶限制的子序列和 hard

題目鏈接

給你一個(gè)整數(shù)數(shù)組 nums 和一個(gè)整數(shù) k ,請(qǐng)你返回 非空 子序列元素和的最大值
子序列需要滿足:子序列中每?jī)蓚€(gè) 相鄰 的整數(shù) nums[i] 和 nums[j] ,它們?cè)谠瓟?shù)組中的下標(biāo) i 和 j 滿足 i < j 且 j - i <= k 。

數(shù)組的子序列定義為:將數(shù)組中的若干個(gè)數(shù)字刪除(可以刪除 0 個(gè)數(shù)字),剩下的數(shù)字按照原本的順序排布。

示例 1: 輸入:nums = [10,2,-10,5,20], k = 2 輸出:37 解釋:子序列為 [10, 2, 5, 20] 。示例 2: 輸入:nums = [-1,-2,-3], k = 1 輸出:-1 解釋:子序列必須是非空的,所以我們選擇最大的數(shù)字。示例 3: 輸入:nums = [10,-2,-10,-5,20], k = 2 輸出:23 解釋:子序列為 [10, -2, -5, 20] 。提示: 1 <= k <= nums.length <= 10^5 -10^4 <= nums[i] <= 10^4

解答:

  • 此題跟 LeetCode 239. 滑動(dòng)窗口最大值(雙端隊(duì)列+單調(diào)棧) 非常類似,可以先看這題

  • dp[i] 表示包含 i 位置的 最大子序和

  • deque 里面保持遞減狀態(tài)(dp值遞減,實(shí)際存儲(chǔ)下標(biāo)),距離超過 k 的,從隊(duì)頭出去

  • 隊(duì)頭(最大的)>0,則 dp[i] = dp[q.front()]+nums[i],否則,dp[i] = nums[i]

  • 然后檢查 dp[i] 要入隊(duì),隊(duì)內(nèi)是否單調(diào)遞減,不滿足,要pop_back()

class Solution { public:int constrainedSubsetSum(vector<int>& nums, int k) {int i, n = nums.size(), maxsum = INT_MIN;vector<int> dp(n, 0);dp[0] = nums[0];maxsum = nums[0];deque<int> q;q.push_back(0);for(i = 1; i < n; i++) {if(i-q.front() > k)//距離超過k了q.pop_front();if(dp[q.front()] > 0)//最大的大于0,可以變大dp[i] = dp[q.front()]+nums[i];else//不能變大,自己就是自己dp[i] = nums[i];maxsum = max(maxsum,dp[i]);//更新最大值while(!q.empty() && dp[i] >= dp[q.back()])q.pop_back();//不滿足單點(diǎn)遞減,pop_backq.push_back(i);}return maxsum;} };

112 ms 14.7 MB

總結(jié)

以上是生活随笔為你收集整理的LeetCode 第 186 场周赛(1060/3107,前34.1%)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。