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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

leetcode 第 216 场周赛 整理

發布時間:2023/12/1 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 leetcode 第 216 场周赛 整理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

  • 1662. 檢查兩個字符串數組是否相等
    • 題目
    • 自己代碼
  • 5606. 具有給定數值的最小字符串
    • 題目
    • 自己代碼
    • 貪心算法
  • 1664. 生成平衡數組的方案數
    • 題目
    • 自己代碼
    • 動態規劃優化
  • 1665. 完成所有任務的最少初始能量
    • 題目
    • 思路

1662. 檢查兩個字符串數組是否相等

題目

給你兩個字符串數組 word1 和 word2 。如果兩個數組表示的字符串相同,返回 true ;否則,返回 false 。

數組表示的字符串 是由數組中的所有元素 按順序 連接形成的字符串。

自己代碼

累加,然后判斷是否相等

class Solution { public:bool arrayStringsAreEqual(vector<string>& word1, vector<string>& word2) {string str1="";string str2="";for(int i=0;i<word1.size();i++){str1+=word1[i];}for(int i=0;i<word2.size();i++){str2+=word2[i];}if(str1==str2) return true;else return false;} };

5606. 具有給定數值的最小字符串

題目

小寫字符 的 數值 是它在字母表中的位置(從 1 開始),因此 a 的數值為 1 ,b 的數值為 2 ,c 的數值為 3 ,以此類推。

字符串由若干小寫字符組成,字符串的數值 為各字符的數值之和。例如,字符串 “abe” 的數值等于 1 + 2 + 5 = 8 。

給你兩個整數 n 和 k 。返回 長度 等于 n 且 數值 等于 k 的 字典序最小 的字符串。

自己代碼

記錄一下自己超時的代碼:
使用的回溯法,這一題使用回溯法并不好,字母越多,解空間樹就會越大,并且沒有使用高效的剪枝手段。

class Solution { public:int sum;int num;string res;char zimu[27]={'a','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};bool backtracking(int n,int k){if(num > n || sum > k || (num<n && sum<k && 26*(n-num)<(k-sum))){return false;}//找到了n個數if(num == n && sum == k){return true;}for(int i=1;i<=26;i++){//處理結點;string new_res = res;res+=(zimu[i]);sum+=i;num+=1;//遞歸,探索下一層if(backtracking(n,k)==true) return true; sum-=i;num-=1;//回溯,撤銷處理結果res=new_res;}return false;}string getSmallestString(int n, int k) {res="";sum=0;num=0;backtracking(n,k);return res;} };

貪心算法

構造出的字符串字典序最小,可以考慮貪心地從字符串的開頭處開始構造,每次選擇一個滿足要求的最小字母。
假設我們當前構造到了某一個位置,包括此位置還剩下n’個位子沒有放入字符,并且這些位子的數值之和為k’;
那么如果我們放入字母c,那么剩余n’-1個位置以及k’-c的數值和必須滿足:
n’-1<=k’-c<=26(n’-1)
(位置數 <= 位置數上的數值和 <= 位置數能放的最多的數值和);
這樣就能得到c的取值范圍:
k’ - 26(n’-1) <= c <= k’ - (n’-1)
這樣就能得到c的取值下限k’ - 26(n’-1);
如果下限小于等于0,我們取a(這是我們能取的當中最小的)
如果下限大于0,那么選擇數值對應的字符。
總的來說,就是從第一位到最后一位都取當前能夠取的最小值,這樣就能保證構造出來的字符串字典序最小了。

class Solution { public:string getSmallestString(int n, int k) {int post_unused=n;int sum_left=k;string result="";while(post_unused!=0){int c=1;if(sum_left - 26*(post_unused-1)<=0) c=1;else c=sum_left - 26*(post_unused-1);result+=c-1+'a';post_unused--;sum_left-=c;}return result;} };

按照這個思路寫一遍。
我他媽傻了,貪心也太牛了,學習了。

1664. 生成平衡數組的方案數

題目

給你一個整數數組 nums 。你需要選擇 恰好 一個下標(下標從 0 開始)并刪除對應的元素。請注意剩下元素的下標可能會因為刪除操作而發生改變。

比方說,如果 nums = [6,1,7,4,1] ,那么:

選擇刪除下標 1 ,剩下的數組為 nums = [6,7,4,1] 。
選擇刪除下標 2 ,剩下的數組為 nums = [6,1,4,1]。
選擇刪除下標 4 ,剩下的數組為 nums = [6,1,7,4] 。
如果一個數組滿足奇數下標元素的和與偶數下標元素的和相等,該數組就是一個 平衡數組 。

請你返回刪除操作后,剩下的數組 nums 是 平衡數組 的 方案數 。

自己代碼

又是一個超時代碼

先講講思路:
首先nums數組中的每個位置都定義四個相應數組:
分別用來記錄i之前的偶數之和,i之前的奇數之和,i之后的偶數之和,i之后的奇數之和。
然后開始遍歷這個數組,記錄每個位子的四個數組數值。
去除索引為i的元素后,i之前元素的奇偶性不變,i之后元素的奇偶性改變,即i之后奇/偶數下標元素的和變成了偶/奇數下標。
然后暴力解:滿足奇數下標元素的和與偶數下標元素的和相等

class Solution { public:int waysToMakeFair(vector<int>& nums) {int fangannums=0;for(int i=0;i<nums.size();i++){vector<int> sum={0,0,0,0};for(int j=0;j<i;j+=2){sum[0]+=nums[j];}for(int j=1;j<i;j+=2){sum[1]+=nums[j];}if(i%2==0){for(int j=i+1;j<nums.size();j+=2){sum[2]+=nums[j];}for(int j=i+2;j<nums.size();j+=2){sum[3]+=nums[j];} }else{for(int j=i+1;j<nums.size();j+=2){sum[3]+=nums[j];}for(int j=i+2;j<nums.size();j+=2){sum[2]+=nums[j];} }if(sum[0]+sum[2] == sum[1]+sum[3]) fangannums+=1;}return fangannums;} };

動態規劃優化

之前超時很明顯就是四個數組值重復計算:i之前的偶數之和,i之前的奇數之和,i之后的偶數之和,i之后的奇數之和。
現在直接看下標,這樣不容易混淆,下標是偶數,數組名字中就有even,下標是奇數,名字中就有odd。
步驟如下:


需要特別注意的地方:
dp推導:
注意這里我們四個數組都不會將nums[i]包括進去的。
i為偶數的話,i-1是奇數,所以左偶和[i] = 左偶和[i-1],左奇和[i] = 左奇和[i-1]+nums[i-1];
i為奇數的話,i-1是偶數,所以左偶和[i] = 左偶和[i-1]+nums[i-1],左奇和[i] = 左奇和[i-1];
這樣一來,就能對計算i之前的偶數和,奇數和省下時序。沒必要每次都從i=0開始判斷累加。
其次,i右邊的偶數和,奇數和也沒必要通過for運算開始計算,而是只需要從sum_odd和sum_even中視情況減去左偶右偶、nums[i]即可。
這樣也是同時省下大把時序。

//如果i是偶數下標,i-1為奇數下標 if(i%2==0) {before_i_evensum[i]=before_i_evensum[i-1];before_i_oddsum[i]=before_i_oddsum[i-1]+nums[i-1]; } else {before_i_evensum[i]=before_i_evensum[i-1]+nums[i-1];before_i_oddsum[i]=before_i_oddsum[i-1]; } class Solution { public:int waysToMakeFair(vector<int>& nums) {int fangannums=0;int n = nums.size();//i左邊偶數下標所指數之和vector<int> before_i_evensum(n,0);//i左邊奇數下標所指數之和vector<int> before_i_oddsum(n,0);//i右邊偶數下標所指數之和vector<int> after_i_evensum(n,0);//i右邊偶數下標所指數之和vector<int> after_i_oddsum(n,0);//*******【1】計算數組的奇數下標和以及偶數下標和***//int sum_odd=0;int sum_even=0;for(int i=0;i<n;i++){if(i%2==0) sum_even+=nums[i];else sum_odd+=nums[i];}//****************************************//for(int i=0;i<n;i++){if(i==0){after_i_evensum[0]=sum_even - nums[i];after_i_oddsum[0] = sum_odd; }else{//*******【2】i之前的偶數下標和以及奇數下標和***////如果i是偶數下標,i-1為奇數下標if(i%2==0) {before_i_evensum[i]=before_i_evensum[i-1];before_i_oddsum[i]=before_i_oddsum[i-1]+nums[i-1];after_i_evensum[i]=sum_even - before_i_evensum[i] - nums[i];after_i_oddsum[i] = sum_odd - before_i_oddsum[i];}//如果i是奇數下標,i-1為偶數下標else{before_i_evensum[i]=before_i_evensum[i-1]+nums[i-1];before_i_oddsum[i]=before_i_oddsum[i-1];after_i_evensum[i]=sum_even - before_i_evensum[i];after_i_oddsum[i] = sum_odd - before_i_oddsum[i] - nums[i];}}if(before_i_evensum[i]+after_i_oddsum[i] == before_i_oddsum[i]+after_i_evensum[i])fangannums++; }return fangannums;} };


這一題當時并沒有做出來,是剛剛才想到的。

1665. 完成所有任務的最少初始能量

題目

給你一個任務數組 tasks ,其中 tasks[i] = [actuali, minimumi] :

actuali 是完成第 i 個任務 需要耗費 的實際能量。
minimumi 是開始第 i 個任務前需要達到的最低能量。
比方說,如果任務為 [10, 12] 且你當前的能量為 11 ,那么你不能開始這個任務。如果你當前的能量為 13 ,你可以完成這個任務,且完成它后剩余能量為 3 。

你可以按照 任意順序 完成任務。

請你返回完成所有任務的 最少 初始能量。




思路

觀察示例,可以發現,完成的任務是按照最(低能量-實際能量)的大小來排序的,差越大的越先被執行。
https://leetcode-cn.com/problems/minimum-initial-energy-to-finish-tasks/solution/wan-cheng-suo-you-ren-wu-de-zui-shao-chu-shi-neng-/
神仙題目,這里貼個代碼:

class Solution { public:static bool cmp(vector<int>& p1, vector<int>& p2) {return p1[1] - p1[0] > p2[1] - p2[0];}int minimumEffort(vector<vector<int>>& tasks) {sort(tasks.begin(), tasks.end(),cmp);int sum=0; //完成任務需要消耗的實際能量int ans=0; //完成任務需要達到的最低能量//打印信息// for(auto& task : tasks)// {// cout<<"task[0]:"<<task[0]<<" task[1]:"<<task[1]<<endl;// }for(auto& task : tasks){//cout<<"ans:"<<ans<<" sum:"<<sum<<endl;ans = max(ans,sum+task[1]);sum +=task[0];}return ans;} }; 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的leetcode 第 216 场周赛 整理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。