【Leetcode周賽】從contest-51開始。(通常是10個contest寫一篇文章)

Contest 51 (2018年11月22日,週四早上)(題號681-684)

連接:https://leetcode.com/contest/leetcode-weekly-contest-51git

比賽結果記錄:3/4,ranking:270/2879。第三題有點相似於圖的最小生成樹,第四題彷佛是很火的種花題(第四題我好像幾個月以前作過,有印象,當時也是本身作的)。數組

【682】Baseball Game(第一題 3分)數據結構

You're now a baseball game point recorder.app

Given a list of strings, each string can be one of the 4 following types:ide

  1. Integer (one round's score): Directly represents the number of points you get in this round.
  2. "+" (one round's score): Represents that the points you get in this round are the sum of the last two valid round's points.
  3. "D" (one round's score): Represents that the points you get in this round are the doubled data of the last valid round's points.
  4. "C" (an operation, which isn't a round's score): Represents the last valid round's points you get were invalid and should be removed.

Each round's operation is permanent and could have an impact on the round before and the round after.this

You need to return the sum of the points you could get in all the rounds. spa

Example 1:
Input: ["5","2","C","D","+"]
Output: 30
Explanation: 
Round 1: You could get 5 points. The sum is: 5.
Round 2: You could get 2 points. The sum is: 7.
Operation 1: The round 2's data was invalid. The sum is: 5.  
Round 3: You could get 10 points (the round 2's data has been removed). The sum is: 15.
Round 4: You could get 5 + 10 = 15 points. The sum is: 30.

Example 2:
Input: ["5","-2","4","C","D","9","+","+"]
Output: 27
Explanation: 
Round 1: You could get 5 points. The sum is: 5.
Round 2: You could get -2 points. The sum is: 3.
Round 3: You could get 4 points. The sum is: 7.
Operation 1: The round 3's data is invalid. The sum is: 3.  
Round 4: You could get -4 points (the round 3's data has been removed). The sum is: -1.
Round 5: You could get 9 points. The sum is: 8.
Round 6: You could get -4 + 9 = 5 points. The sum is 13.
Round 7: You could get 9 + 5 = 14 points. The sum is 27.

Note:
The size of the input list will be between 1 and 1000.
Every integer represented in the list will be between -30000 and 30000.

題解:模擬題,用了一個deque作的模擬,應該能夠有不用數據結構的方法?2 pass3d

 1 class Solution {
 2 public:
 3     int calPoints(vector<string>& ops) {
 4         deque<int> dq;
 5         const int n = ops.size();
 6         for (auto s : ops) {
 7             if (s == "C") {
 8                 if (!dq.empty()) {
 9                     dq.pop_back();
10                 }
11             } else if (s == "D") {
12                 if (!dq.empty()) {
13                     dq.push_back(dq.back() * 2);
14                 }
15             } else if (s == "+") {
16                 int numA = 0;
17                 if (!dq.empty()) {
18                     numA = dq.back();
19                     dq.pop_back();
20                     if (!dq.empty()) {
21                         int temp = dq.back() + numA;
22                         dq.push_back(numA);
23                         dq.push_back(temp);
24                     } else {
25                         dq.push_back(numA);
26                     }
27                 }
28             } else {
29                 dq.push_back(stoi(s));
30             }
31         }
32         int ret = 0;
33         while (!dq.empty()){
34             ret += dq.front();
35             dq.pop_front();
36         }        
37         return ret;
38     }
39 };
View Code

  

【681】Next Closest Time(第二題 6分)調試

給了一個時間表示,格式是 "HH:MM",用如今時間表示的這些數字造成下一個距離如今最近的時間字符串,而且返回. code

You may assume the given input string is always valid. For example, "01:34", "12:09" are all valid. "1:34", "12:9" are all invalid.

Example 1:
Input: "19:34"
Output: "19:39"
Explanation: The next closest time choosing from digits 1, 9, 3, 4, is 19:39, which occurs 5 minutes later.  It is not 19:33, because this occurs 23 hours and 59 minutes later.

Example 2:
Input: "23:59"
Output: "22:22"
Explanation: The next closest time choosing from digits 2, 3, 5, 9, is 22:22. It may be assumed that the returned time is next day's time since it is smaller than the input time numerically.

題解:感受和產生下一個迴文串比較相似,先把這四個數字記下來,而後從後往前找第一個在合理的範圍內能變得更大的數字。由於是時間,因此時針最多到23,分針最多到59,找到第一個能變得更大的數字就把它變得更大,而後把它後面的數字都變成最小。若是找不到這樣的一數字,好比eg2的 23:59,就把全部的數字變成最小的數字,算做新的一天。

 1 class Solution {
 2 public:
 3     string nextClosestTime(string time) {
 4         set<int> st;
 5         int minn = 10;
 6         for (int i = 0; i < 5; ++i) {
 7             if (isdigit(time[i])) {
 8                 int t = time[i] - '0';
 9                 minn = min(t, minn);
10                 st.insert(t);
11             }
12         }
13         if (st.size() == 1) {return time;} //invalid
14         string ret = time;
15         for (int i = 4; i >= 0; --i) {
16             char c = ret[i];
17             int t = c - '0';
18             auto iter = upper_bound(st.begin(), st.end(), t);
19             if (iter == st.end()) {continue;}
20             if (i == 0 && *iter > 2) {
21                 continue;
22             }
23             if (i == 1 && *iter > 4 && ret[0] == '2') {
24                 continue;
25             }
26             if (i == 3 && *iter > 5) {
27                 continue;
28             }
29             ret[i] = (*iter) + '0';
30             for (int k = i + 1; k < 5; ++k) {
31                 if (isdigit(ret[k])) {
32                     ret[k] = minn + '0';
33                 }
34             }
35             break;
36         }
37         if (ret == time) {
38             for (auto& c : ret) {
39                 if (isdigit(c)) {
40                     c = minn + '0';
41                 }
42             }
43         }
44         return ret;
45         
46     }
47 };
View Code

 

【684】Redundant Connection(第三題 8分)

在本題中,樹是一個無環的無向圖。輸入一個N個結點(編號是1~N)的圖,有一條邊是多餘的,把這條邊找出來。 

Example 1:
Input: [[1,2], [1,3], [2,3]]
Output: [2,3]
Explanation: The given undirected graph will be like this:
  1
 / \
2 - 3

Example 2:
Input: [[1,2], [2,3], [3,4], [1,4], [1,5]]
Output: [1,4]
Explanation: The given undirected graph will be like this:
5 - 1 - 2
    |   |
    4 - 3

Note:
The size of the input 2D-array will be between 3 and 1000.
Every integer represented in the 2D-array will be between 1 and N, where N is the size of the input array.

題解:我是用並查集解的。對於每一條邊的兩個結點,若是他們的爸爸不是同一個爸爸,那麼就 unoin 這兩個結點,若是他們兩個的爸爸是同一個爸爸,就說明這條邊多餘了,直接返回這條邊就好了。 

 1 class Solution {
 2 public:
 3     int findfather(int x) {
 4         return x == father[x] ? x : findfather(father[x]);
 5     }
 6     void unionNode(int x, int y) {
 7         x = findfather(x);
 8         y = findfather(y);
 9         if (x == y) { return; }
10         father[y] = x;
11     }
12     
13     vector<int> findRedundantConnection(vector<vector<int>>& edges) {
14         n = edges.size();
15         father.resize(n+1);  //redundant 0
16         for (int i = 0; i < n+1; ++i) {
17             father[i] = i;
18         }
19         vector<int> ret;
20         for (auto e : edges) {
21             int u = min(e[0], e[1]), v = max(e[0], e[1]);
22             if (findfather(v) == findfather(u)) {
23                 ret = e;
24                 break;
25             } else {
26                 unionNode(u, v);
27             }
28         }
29         return ret;
30     }
31     int n = 0;
32     vector<int> father;
33     
34 };
View Code

 

【683】K Empty Slots(第四題 9分)(經典的種花題)

給了 N 個花槽,有 N 朵花天天開一朵,用 flower[i] = x 表示在第 i 天在位置 x 開出了一朵花,花開了以後就會一直開着,不會凋謝。問是否存在這麼一天,某個位置的一朵花開了,而後另一朵花也在開花的狀態,這兩朵花中間有剛好有 k 個花槽,這 k 個花槽都沒有開花。

題解:這題其實以前作過,第一次作就會作,有點倒排索引的感受。咱們用另一個數組 bloom[pos] = day,表示第pos個位置的花在第 day 天開。而後咱們從次日開始枚舉,找到次日開花的位置,而後用 k 計算出另一朵花的位置,看是否已經開花,若是已經開花了,就看一下中間的 k 個花槽是否是都沒開花,若是都知足條件,直接返回這一天。

我今天第一次寫的時候犯了一個誤區,就是我錯誤的認爲若是今天開花,那麼它對應的另一朵花必定是昨天開的,事實上它對應的花能夠在今天前面的任何一天開花。因此會錯。 

 1 //這題一開始有個思惟誤區,就是我懵逼的認爲若是知足條件的那天開的那朵花,與這朵花相對應的另一朵必定開在知足條件的前一天orz。
 2 class Solution {
 3 public:
 4     int kEmptySlots(vector<int>& flowers, int k) {
 5         const int n = flowers.size();
 6         vector<int> bloom(n + 1, 0);
 7         for (int i = 0; i < flowers.size(); ++i) {
 8             int day = i+1, pos = flowers[i]; //day (1, n)
 9             bloom[pos] = day;
10         }
11         //find pos flowers[day-1]
12         for (int day = 2; day < n; ++day) {
13             int posToday = flowers[day-1];
14             for (int m = 0; m < 2; ++m) {
15                 int posPre = m == 0 ? (posToday + k + 1) : (posToday - k - 1);
16                 if (posPre > 0 && posPre <= n) {
17                     int preDay = bloom[posPre];
18                     if (preDay > day) {continue;}
19                     bool valid = true;
20                     for (int i = min(posPre, posToday) + 1; i < max(posPre, posToday); ++i) {
21                         if (bloom[i] < day) {
22                             valid = false;
23                             break;
24                         }
25                     }
26                     if (valid) {return day;}
27                 }
28             }
29         }
30         return -1;
31     }
32 };
View Code

 

 

Contest 52 (2018年11月24日,週六下午)(題號686-689)

比賽狀況記錄:2/4,rank:485/2615. 第三題機率題不會作,第四題感受方法對了,可是代碼寫出來踩內存了RE,調試了一夜也沒搞明白到底哪裏問題。mdzz。

連接:https://leetcode.com/contest/leetcode-weekly-contest-52

【686】Repeated String Match(第一題 3分)

第一題給了兩個字符串,A 和 B, 問 A 倍增幾倍以後能不能把 B 變成它的子串。返回 A 倍增的最小次數,若是不管怎麼倍增 B 都不是子串的話,返回 -1。

題解:本題一開始還有點卡住了orz,尷尬。先求 A B 的長度,若是 A 的長度直接比 B 大的話,最多 2 個 A能夠搞成 B。同理,先求 Asize / Bsize,先把 A 的長度倍增成比B大一點點或者相等,若是這時候 B 還不是 A 的子串,就把再加一個 A,若是加了還不是就是否是了。

 1 class Solution {
 2 public:
 3     int repeatedStringMatch(string A, string B) {
 4         const int Asize = A.size(), Bsize = B.size();
 5         int t = Bsize / Asize;
 6         if (Asize * t < Bsize) {++t;}
 7         string newA = "";
 8         for (int i = 0; i < t; ++i) {
 9             newA += A;
10         }
11         if (newA.find(B) == string::npos) {
12             newA += A;
13             if (newA.find(B) == string::npos) {
14                 return -1;
15             }
16             return t+1;
17         }
18         return t;
19     }
20 };
View Code

 

【687】Longest Univalue Path(第二題 5分)

 

【688】Knight Probability in Chessboard(第三題 6分)

 

【689】Maximum Sum of 3 Non-Overlapping Subarrays(第四題 8分)

 

 

Contest 53 ()(題號)

Contest 54 ()(題號)

Contest 55 ()(題號)

Contest 56 ()(題號)

Contest 57 ()(題號)

Contest 58 ()(題號)

Contest 59 ()(題號)

Contest 60 (2018年12月26日,週三早上)(題號)

連接:https://leetcode.com/contest/weekly-contest-60

比賽結果記錄:3/4,沒開 virtual,因此我也沒有記錄具體的時間。orz。第四題研究了一下子,須要遞歸作。然而本身放棄了沒寫出來。

【733】Flood Fill(第一題 3分)

給了一個二維的matrix,和一個點座標,和新顏色。把這個點周圍四聯通區域和該點相同顏色的點,都染成新的顏色。

題解:無

 1 class Solution {
 2 public:
 3     vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int newColor) {
 4         n = image.size(), m = image[0].size();
 5         oric = image[sr][sc];
 6         if (oric == newColor) {return image;}
 7         floodfill (image, sr, sc, newColor);
 8         return image;
 9     }
10     int n, m;
11     int oric;
12     void floodfill(vector<vector<int>>& image, int cur_x, int cur_y, const int color) {
13         image[cur_x][cur_y] = color;
14         for (int i = 0; i < 4; ++i) {
15             int newx = cur_x + dirx[i], newy = cur_y + diry[i];
16             if (newx < 0 || newx >= n || newy < 0 || newy >= m || image[newx][newy] != oric) {
17                 continue;
18             }
19             floodfill(image, newx, newy, color);
20         }
21     }
22     int dirx[4] = {-1, 0, 1, 0};
23     int diry[4] = {0, -1, 0, 1};
24 };
View Code

 

【734】Sentence Similarity(第二題 3分)

給了兩個單詞數組,words1,words2,和一個類似單詞的詞典,判斷這兩個單詞數組是否是類似。類似的條件爲(1)兩個數組元素個數一致;(2)words1[i], words2[i] 在類似詞典中有映射關係,或者words1[i] 和 words2[i] 這兩個單詞相同。

題解:無

 1 class Solution {
 2 public:
 3     bool areSentencesSimilar(vector<string>& words1, vector<string>& words2, vector<pair<string, string>> pairs) {
 4         const int n1 = words1.size(), n2 = words2.size();
 5         if (n1 != n2) {return false;}
 6         set<pair<string, string>> st(pairs.begin(), pairs.end());
 7         bool flag = true;
 8         for (int i = 0; i < n1; ++i) {
 9             string s1 = words1[i], s2 = words2[i];
10             if (s1 == s2) {continue;}
11             pair<string, string> p1 = make_pair(s1, s2), p2 = make_pair(s2, s1);    
12             if (st.find(p1) == st.end() && st.find(p2) == st.end()) {
13                 flag = false;
14                 break;
15             }
16         }
17         return flag;
18     }
19 };
View Code

 

【735】Asteroid Collision(第三題 5分)

給了一個數組 asteroids 表明一排小行星,元素絕對值表明行星大小,正數表明行星向右,負數表明向左。(若是前面行星向右,後面行星向左,就必定會相撞。可是若是同向或者相背,就確定不會相撞)若是兩顆行星相撞,小的會爆炸,若是大小相同就都爆炸。問最後剩下的行星,返回這個數組。

題解:用一個 vector 或者 deque 存儲已經遍歷過的行星,若是當前元素是負數,就要一直和前面的正數行星相撞,直到前面沒有正數行星爲止。有點相似業務邏輯題了。時間複雜度是 O(N)。本題用vector更合適。

 1 class Solution {
 2 public:
 3     vector<int> asteroidCollision(vector<int>& asteroids) {
 4         const int n = asteroids.size();
 5         deque<int> dq;
 6         for (auto ast : asteroids) {
 7             if (dq.empty()) {
 8                 dq.push_back(ast);
 9             } else {
10                 bool needPush = true;
11                 while (!dq.empty() && dq.back() > 0 && ast < 0) {
12                     if (abs(dq.back()) == abs(ast)) {
13                         dq.pop_back();
14                         needPush = false;
15                         break;
16                     } else if (abs(dq.back() < abs(ast))) {
17                         dq.pop_back();
18                     } else {
19                         needPush = false;
20                         break;
21                     }
22                 } 
23                 if (needPush) {
24                     dq.push_back(ast);
25                 }
26             }
27         }
28         vector<int> ret(dq.size());
29         int i = 0;
30         while (!dq.empty()) {
31             ret[i++] = dq.front();
32             dq.pop_front();
33         }
34         return ret;
35     }
36 };
View Code

 

【】Parse Lisp Expression(第四題 9分)

相關文章
相關標籤/搜索