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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

LeetCode之Weekly Contest 90

發布時間:2024/4/15 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LeetCode之Weekly Contest 90 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

LeetCode第90場周賽記錄

第一題:親密字符串

問題:

給定兩個由小寫字母構成的字符串?A?和?B?,只要我們可以通過交換?A?中的兩個字母得到與?B?相等的結果,就返回?true?;否則返回?false?。

示例 1:

輸入: A = "ab", B = "ba" 輸出: true

示例 2:

輸入: A = "ab", B = "ab" 輸出: false

示例 3:

輸入: A = "aa", B = "aa" 輸出: true

示例 4:

輸入: A = "aaaaaaabc", B = "aaaaaaacb" 輸出: true

示例 5:

輸入: A = "", B = "aa" 輸出: false

鏈接:https://leetcode-cn.com/contest/weekly-contest-90/problems/buddy-strings/

分析:

1.如果兩個字符串長度不等,一定不滿足

2.如果兩個字符串完全相同,需要至少兩個完全相同的字符,才能滿足交換兩個字母后相同,所以如果長度小于2,也一定不滿足。

3.其他情況兩個字符串需要有且僅有兩個不同的字符,差異的兩個字符僅僅是順序不同。

?

AC Code:

1 class Solution { 2 public: 3 bool buddyStrings(string A, string B) { 4 if (A.size() != B.size() || A.size()<2) 5 { 6 return false; 7 } 8 //記錄不同的,如果兩者可以交換,返回true,完全相同,返回true 9 int counter = 0; //記錄差異點數 10 string A1=""; //分別保存差異內容 11 string A2=""; 12 for (int i = 0; i < A.size(); i++) 13 { 14 if (A[i] != B[i]) 15 { 16 counter++; 17 A1 += A[i]; 18 A2 += B[i]; 19 } 20 } 21 if (counter == 0) 22 { 23 //完全一樣的兩個字符串 24 //需要有兩個完全一樣的字符 25 map<char, int> tmp; 26 for (int i = 0; i < A.size(); i++) 27 { 28 if (tmp.count(A[i])==1) 29 { 30 tmp[A[i]]++; 31 } 32 else 33 { 34 tmp[A[i]] = 1; 35 } 36 } 37 map<char, int>::iterator it; 38 for (it = tmp.begin(); it != tmp.end(); it++) 39 { 40 if (it->second >= 2) 41 { 42 return true; 43 } 44 } 45 return false; 46 } 47 if (A1.size()!=2) 48 { 49 return false; 50 } 51 else 52 { 53 if (A1[0] == A2[1] && A1[1] == A2[0]) 54 { 55 return true; 56 } 57 else 58 { 59 return false; 60 } 61 } 62 } 63 };

其他:

第一的做法:

1 class Solution { 2 public boolean buddyStrings(String A, String B) { 3 int[] l = new int[256]; 4 boolean two = false; 5 for(int i = 0; i < A.length(); i++) { 6 if(++l[A.charAt(i)] > 1) two = true; 7 } 8 for(int i = 0; i < B.length(); i++) { 9 --l[B.charAt(i)]; 10 } 11 for(int out: l) { 12 if(out != 0) return false; 13 } 14 int error = 0; 15 for(int i = 0; i < A.length(); i++) { 16 if(A.charAt(i) != B.charAt(i)) { 17 error++; 18 } 19 } 20 if(error == 2) return true; 21 if(error > 2) return false; 22 return two; 23 } 24 }

用的好像是Java,思路是先創建256大小字符數組【如果要對空間進行優化的話,可以只創建26個大小數組,因為題目中明確只有a-z,對應做一個-‘a’處理即可,不過區別不大】,用來統計每個字母出現個數,先統計A的數量,一旦有某個字符出現兩次及以上,將標志two設為true。然后利用B中字符減去對應個數,結束后一旦某個字符對應位置不是0,則說明A中和B中對應字符個數不一致,一定不滿足要求,返回false,然后統計AB中差異個數,如果差異個數是2,返回true,如果差異超過2,返回false,接下來一定是沒有差異(如果只有一個字符差異,一定不滿足AB中對應字符個數一致要求,前面就會返回false),返回two的值,即是否有某個字符數量達到2.

?

第二題:括號的分數

題目:

給定一個平衡括號字符串?S,按下述規則計算該字符串的分數:

  • ()?得 1 分。
  • AB?得?A + B?分,其中 A 和 B 是平衡括號字符串。
  • (A)?得?2 * A?分,其中 A 是平衡括號字符串。

示例 1:

輸入: "()" 輸出: 1

示例 2:

輸入: "(())" 輸出: 2

示例?3:

輸入: "()()" 輸出: 2

示例?4:

輸入: "(()(()))" 輸出: 6

提示:

  • S?是平衡括號字符串,且只含有?(?和?)?。
  • 2 <= S.length <= 50
  • 鏈接:https://leetcode-cn.com/contest/weekly-contest-90/problems/score-of-parentheses/

    ?

    分析:

    1.如果是(),值為1;

    2.如果是“”,值為0;

    3.對于某個string S,如果形如()S`,結果為1+value(S`)

    如果形如(S`)S``,結果為2*value(S`)+value(S``)

    已知給出字符串是平衡的,只需要按照規則遞歸分解求值即可

    需要做的就是找出S`以及剩余字符串S``

    AC code:

    ?

    1 class Solution { 2 public: 3 int scoreOfParentheses(string S) { 4 if (S.size() == 0) //空串值為0 5 { 6 return 0; 7 } 8 if (S.size() == 2) //已知括號匹配,長度2的一定是(),值是1 9 { 10 return 1; 11 } 12 string tmp = ""; //嵌套的字符串 13 string left = ""; //當前匹配后剩余的字符串 14 stack<char> tmpstack; //S[0]一定是'(' 15 if (S[1] == ')') // ()S`類型 16 { 17 for (int j = 2; j < S.size(); j++) 18 { 19 left += S[j]; 20 } 21 return 1 + scoreOfParentheses(left);; 22 } 23 tmp += S[1]; 24 tmpstack.push(S[1]); 25 for (int i = 2; i < S.size(); i++) 26 { 27 if (tmpstack.empty() == true && S[i] == ')') //完成匹配,形如(S`)S`` 28 { 29 for (int j = i + 1; j < S.size(); j++) 30 { 31 left += S[j]; 32 } 33 return 2 * scoreOfParentheses(tmp) + scoreOfParentheses(left); 34 } 35 else 36 { 37 tmp += S[i]; 38 if (tmpstack.empty() == true) 39 { 40 tmpstack.push(S[i]); 41 } 42 else if (tmpstack.top() == '(' && S[i] == ')') 43 { 44 tmpstack.pop(); 45 } 46 else 47 { 48 tmpstack.push(S[i]); 49 } 50 } 51 } 52 53 } 54 };

    其他:

    第一的做法:

    1 class Solution { 2 public int scoreOfParentheses(String S) { 3 if(S.length() == 0) return 0; 4 if(S.charAt(0) == '(' && S.charAt(1) == ')') { 5 return 1 + scoreOfParentheses(S.substring(2)); 6 } 7 int d = 0; 8 int end = -1; 9 for(int i = 0; i < S.length(); i++) { 10 if(S.charAt(i) == '(') d++; 11 else d--; 12 if(d == 0) { 13 end = i+1; 14 break; 15 } 16 } 17 return 2 * scoreOfParentheses(S.substring(1, end-1)) + scoreOfParentheses(S.substring(end)); 18 } 19 }

    基本思路基本一致,處理(S`)S``類型時候沒有使用棧而是直接通過識別‘('和')’加減計數來找到(S`)

    ?

    第三題:鏡面反射

    題目:

    有一個特殊的正方形房間,每面墻上都有一面鏡子。除西南角以外,每個角落都放有一個接受器,編號為?0,?1,以及?2。

    正方形房間的墻壁長度為?p,一束激光從西南角射出,首先會與東墻相遇,入射點到接收器?0?的距離為?q。

    返回光線最先遇到的接收器的編號(保證光線最終會遇到一個接收器)。

    ?

    示例:

    輸入: p = 2, q = 1 輸出: 2 解釋: 這條光線在第一次被反射回左邊的墻時就遇到了接收器 2 。

    ?

    提示:

  • 1 <= p <= 1000
  • 0 <= q <= p
  • ?



    鏈接:https://leetcode-cn.com/contest/weekly-contest-90/problems/mirror-reflection/

    ?

    分析:

    1,利用鏡面反射特點,可以假設上面有無限長,光線一直向上走;

    2,在1的前提下,每反射一次,向上高度增加q;

    3,如果被某個接收器接收到了,說明當前高度是p的整數倍;

    4,如果反射偶數次被接收到,則必定是2號接收到;

    5,如果最終達到的“高度”是墻面高度p的奇數倍,則被1號接收到;

    6,如果最終達到的“高度”是墻面高度p的偶數倍,則被0號接收到;

    分析完成后問題就變得很簡單了。

    AC code:

    1 class Solution { 2 public: 3 int mirrorReflection(int p, int q) { 4 //無限向上延伸,虛擬節點,整數倍獲得結果 5 int counter = 1; 6 while (true) 7 { 8 if (q*counter % p == 0) 9 { 10 if (counter % 2 == 0) 11 { 12 return 2; 13 } 14 if (q*counter / p % 2 == 0) 15 { 16 return 0; 17 } 18 return 1; 19 } 20 counter++; 21 } 22 } 23 };

    其他:

    第一code

    1 class Solution { 2 public int mirrorReflection(int p, int q) { 3 int curr = 0; 4 for(int i = 1; true; i++) { 5 curr += q; 6 curr %= (2*p); 7 if(curr == p) { 8 if(i%2 == 1) { 9 return 1; 10 } 11 else { 12 return 2; 13 } 14 } 15 if(curr == 0) { 16 return 0; 17 } 18 } 19 } 20 }

    假設房間向上翻轉一次,得到一個p寬,2*p高的長方形,curr記錄當前高度(高度范圍[0,2*p)),每次反射高度增加q,如果高度等于0,則會被0號接受,如果高度等于p,則被1或者2接收,其中反射奇數次被1號接收,反射偶數次被2號接收。

    感覺自己的code有一點不好的就是如果pq很大且數據巧合有可能溢出,映射到2p范圍內會更好。

    ?

    第四題:雇傭 K 名工人的最低成本

    題目:

    • 用戶通過次數0
    • 用戶嘗試次數0
    • 通過次數0
    • 提交次數0
    • 題目難度Hard

    有?N?名工人。?第?i?名工人的工作質量為?quality[i]?,其最低期望工資為?wage[i]?。

    現在我們想雇傭?K?名工人組成一個工資組。在雇傭?一組 K 名工人時,我們必須按照下述規則向他們支付工資:

  • 對工資組中的每名工人,應當按其工作質量與同組其他工人的工作質量的比例來支付工資。
  • 工資組中的每名工人至少應當得到他們的最低期望工資。
  • 返回組成一個滿足上述條件的工資組至少需要多少錢。

    示例 1:

    輸入: quality = [10,20,5], wage = [70,50,30], K = 2 輸出: 105.00000

    示例 2:

    輸入: quality = [3,1,10,10,1], wage = [4,8,2,2,7], K = 3 輸出: 30.66667

    提示:

  • 1 <= K <= N <= 10000,其中?N = quality.length = wage.length
  • 1 <= quality[i] <= 10000
  • 1 <= wage[i] <= 10000
  • 與正確答案誤差在?10^-5?之內的答案將被視為正確的。
  • 鏈接:https://leetcode-cn.com/contest/weekly-contest-90/problems/minimum-cost-to-hire-k-workers/

    ?

    分析:

    速度有點慢,最后20分鐘開始處理,沒想太多,測試數據到第41個超時了,O(n*n)毫無前途。

    TimeOut COde:

    1 class Solution { 2 public: 3 double mincostToHireWorkers(vector<int>& quality, vector<int>& wage, int K) { 4 double min = 9999999.0; 5 for (int i = 0; i < quality.size(); i++) 6 { 7 vector<double> tmpmin; 8 double tmp = wage[i]*1.0 / quality[i]; 9 for (int j = 0; j < quality.size(); j++) 10 { 11 if (quality[j] * tmp < wage[j]) 12 { 13 continue; 14 } 15 else 16 { 17 tmpmin.push_back(quality[j] * tmp); 18 } 19 } 20 if (tmpmin.size() < K) 21 { 22 continue; 23 } 24 else 25 { 26 sort(tmpmin.begin(), tmpmin.end()); 27 double tmpsum = 0; 28 for (int index = 0; index < K; index++) 29 { 30 tmpsum += tmpmin[index]; 31 } 32 if (tmpsum < min) 33 { 34 min = tmpsum; 35 } 36 } 37 } 38 return min; 39 } 40 };

    之前想法是算出每個人的“性價比”,即最低要求和工作質量的比值,然后按照該比值衡量所有人,如果該比值下的工資低于最低期望,則不會加入,然后在加入里面選出最低的K個,得到一個總和,按照每個人的標準衡量一遍,所有總和中最低的一個即為符合要求的結果。但是顯然O(n*n)效率太低。

    比賽到時見后參考別人code,發現按照性價比排序后只需要過一遍就能得到結果。

    AC 思路:

    單位工作質量所要工資其實和性價比相反,越低越好。但是并不是說比值越低總價就越低,比如一個工作質量/最低工資分別是[1,10]和[20,40],前者比值10,后者比值2,但是只要1個人的話顯然需要選擇前者。

    按照wget/quality進行升序排序,則只需要獲得quality總和即可,因為所采用的單位質量價值都是相同的,都采用的最低的一個。由于采用的單位質量價值相同,影響最終結果的只有quality值了,則每次需要將前k個中quality最大的一個移除進行后面的嘗試。

    在給出的第一組測試數據中,

    [10,20,5]

    [70,50,30]

    計算wget/quality以及排序后結果如下:

    [20,5.10]

    [50,30,40]

    [2.5,,6,7]

    從中選擇2個,則第一次嘗試結果選擇前兩個,按照6計算,值為(20+5)*6=150

    前面有分析過并非wget/quality低的總和就會少,所以需要進行遍歷嘗試后面的所有值,

    當選擇下一個時候,由于確定比例會選擇7,影響到結果的只有quality值了,20>5,移除20,得到新的組合(5+10)*7=105

    對于第二組測試數據,按照同樣方式處理排序后結果如下

    [10,10,3,1,1]

    [2,2,4,7,8]

    [0.2,0.2,1.3333,7,8]

    選擇3個,第一次前三個組合得到(10+10+3)*1.333=30.6667

    接下來嘗試比例7的,移除前面quality最大的10,(10+3+1)*7=98

    嘗試比例8 ,移除quality最大的10,(3+1+1)*8=40,則最小值30.6667

    ?

    AC code:

    1 class Solution { 2 public: 3 typedef struct Worker 4 { 5 int quality; 6 int wage; 7 double ratio; 8 bool operator< (const Worker &w1) 9 { 10 return ratio < w1.ratio; 11 } 12 }Worker; 13 14 double mincostToHireWorkers(vector<int>& quality, vector<int>& wage, int K) 15 { 16 vector < Worker > workers; 17 for (int i = 0; i < quality.size(); i++) 18 { 19 Worker w = { quality[i], wage[i], wage[i] * 1.0 / quality[i] }; 20 workers.push_back(w); 21 } 22 //按照性價比排序 23 sort(workers.begin(), workers.end()); 24 double ret = INT_MAX; 25 vector<int> tmpqs;//由于性價比是下降的(wget/qualite 上升),即單位質量花費是增加的,所以每次都把前面qualities最大的除去 26 for (int i = 0; i < workers.size(); i++) 27 { 28 if (tmpqs.size() < K) 29 { 30 tmpqs.push_back(workers[i].quality); 31 } 32 if (tmpqs.size() == K) 33 { 34 //得到一個組合,判斷是否更小 35 int tmpsumquality=0; 36 int tmpmaxindex = 0; 37 int tmpmaxquality = INT_MIN; 38 for (int j = 0; j < K; j++) 39 { 40 tmpsumquality += tmpqs[j]; 41 if (tmpqs[j]>tmpmaxquality) 42 { 43 tmpmaxindex = j; 44 tmpmaxquality = tmpqs[j]; 45 } 46 } 47 ret = min(ret, tmpsumquality*workers[i].ratio); 48 //然后需要移除當前最大qualities 49 tmpqs.erase(tmpqs.begin() + tmpmaxindex); 50 } 51 } 52 return ret; 53 } 54 55 56 };

    其他:

    1.DBL_MAX默認是不認的,所以應改為INT_MAX

    2.第一code

    1 class Solution { 2 public double mincostToHireWorkers(int[] quality, int[] wage, int K) { 3 State[] l = new State[quality.length]; 4 for(int i = 0; i < quality.length; i++) { 5 l[i] = new State(quality[i], wage[i]); 6 } 7 Arrays.sort(l); 8 double ret = Double.MAX_VALUE; 9 PriorityQueue<Integer> q = new PriorityQueue<Integer>(); 10 long sum = 0; 11 for(int i = 0; i < l.length; i++) { 12 q.add(-l[i].quality); 13 sum += l[i].quality; 14 if(q.size() > K) { 15 sum += q.poll(); 16 } 17 if(q.size() == K) { 18 ret = Math.min(ret, sum * l[i].ratio()); 19 } 20 } 21 return ret; 22 } 23 class State implements Comparable<State> { 24 public int quality; 25 public int wage; 26 public State(int quality, int wage) { 27 super(); 28 this.quality = quality; 29 this.wage = wage; 30 } 31 public double ratio() { 32 return wage / (double) quality; 33 } 34 public int compareTo(State s) { 35 return Double.compare(ratio(), s.ratio()); 36 } 37 @Override 38 public String toString() { 39 return "State [quality=" + quality + ", wage=" + wage + "]"; 40 } 41 42 } 43 } a.利用了PriorityQueue自動調整結構的特定,通過poll將最大quality移除掉
    b.通過*-1將最小堆轉換為最大堆
    c. 1 for(int i = 0; i < l.length; i++) { 2 q.add(-l[i].quality); 3 sum += l[i].quality; 4 if(q.size() > K) { 5 sum += q.poll(); 6 } 7 if(q.size() == K) { 8 ret = Math.min(ret, sum * l[i].ratio()); 9 } 10 }

    中,q.poll的有可能就是剛插入進去的,比如某個quality最大,同時ratio也比較大的,完全可以直接跳過,也許能夠進一步優化,不過這樣做的好處就是形式的統一。

    ?

    總結:

    第四次參加周賽了,雖說仍然沒能完成四道題,不過至少四個都懂了,也算是有所收獲。和高手比起來,感覺最欠缺的一是速度,二是對語言特性的掌握,三是對常用算法的掌握。

    1.速度上來講第一四道題做完不到20分鐘,自己第一個AC都快18分鐘了,即使會做沒時間做也是白搭,即使是實際項目中,也是越早做出來越早發現問題有時間完善改進。

    2.雖說C/C++/C#/Java/Go/Python/Swift/Kotlin/VB等都稍有涉獵,能拿來用,尤其C/C++從開始于到現在都六七年了,不過僅僅限于基礎用法的使用,好多高階用法并沒掌握,所以一旦需要要么臨時搜索查詢,要么根本就不知道有只能笨拙的自己實現,掌握多門語言固然不錯,但是要有自己的核心技能語言,暫且選擇C++/C#好了,今后不僅要能用,更要用好,要深入理解掌握。

    3.見多方能識廣,承認有天才,但自認為不是,而大多數問題其實都已經存在且被解決,一方面固然需要提高自己的獨立思考能力,另一方面也不能閉門造車,多學習其他人,才能更快的提高。

    化用老師的一句話:大量練習,大量做題,大量閱讀,自然能夠提高。

    practice makes prefect

    轉載于:https://www.cnblogs.com/youdias/p/9220748.html

    總結

    以上是生活随笔為你收集整理的LeetCode之Weekly Contest 90的全部內容,希望文章能夠幫你解決所遇到的問題。

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