Leetcode周赛从contest-111开始。(一般是10个contest写一篇文章)
Posted zhangwanying
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode周赛从contest-111开始。(一般是10个contest写一篇文章)相关的知识,希望对你有一定的参考价值。
Contest 111 ()
链接:https://leetcode.com/contest/weekly-contest-111
Contest 112(2018年11月25日)(题号945~948)
比赛情况记录:这场有点像是贪心专题了orz,结果:1/4,ranking:1383/3195,第一题懵逼的原因是 5-3=3?==。这场真的没有一题难题,然后就是不会做。这就比较尴尬了。
链接:https://leetcode.com/contest/weekly-contest-112
【945】Minimum Increment to Make Array Unique(第一题 5分)
题意是给了一个数组有重复数字,目标是把数组中的元素都变成 unique 的,游戏规则是移动一步可以把一个数字加一。问最少移动几步能把所有数字unique化。
题解:先排序,然后按照排序的数字递增,缺几个就加几。
1 class Solution { 2 public: 3 int minIncrementForUnique(vector<int>& A) { 4 sort(A.begin(), A.end()); 5 const int n = A.size(); 6 int res = 0; 7 for (int i = 1; i < n; ++i) { 8 if (A[i] > A[i-1]) {continue;} 9 int newAi = A[i-1]+1; 10 res += newAi - A[i]; 11 A[i] = newAi; 12 } 13 return res; 14 } 15 };
【946】Validate Stack Sequences(第二题 6分)(我没记错的话这题应该是剑指offer原题)
给了两个 distinct 的序列,问一个作为栈的 push 序列的话,另外一个是否能作为 pop 序列。
题解:直接模拟栈的行为。
1 class Solution { 2 public: 3 bool validateStackSequences(vector<int>& pushed, vector<int>& popped) { 4 const int n = pushed.size(); 5 stack<int> stk; 6 int p1 = 0, p2 = 0; 7 while (p1 < n && p2 < n) { 8 while (stk.empty() || stk.top() != popped[p2]) { 9 stk.push(pushed[p1++]); 10 } 11 while (!stk.empty() && stk.top() == popped[p2]) { 12 stk.pop(); 13 ++p2; 14 } 15 } 16 while (!stk.empty() && stk.top() == popped[p2]) { 17 stk.pop(); 18 ++p2; 19 } 20 return stk.empty(); 21 } 22 };
【947】Most Stones Removed with Same Row or Column(第三题 6分)
【948】Bag of Tokens(第四题 6分)(2018年12月9日,算法群每日一题,补充的周赛解题报告)
题意是给了一个tokens的数组,和一个原始的power P,游戏规则如下:(1)用 tokens[i] 的 power 可以换 1 point; (2) 用 1 point 也可以换 tokens[i] 的power。问最多能换多少 point。
题解:greedy + 2 pointers。排序之后用2 pointers 两遍夹逼。前面的pointer用来换point(一直往前直到当前的power换不起point了), 后面的pointer用来换power。
1 class Solution { 2 public: 3 int bagOfTokensScore(vector<int>& tokens, int P) { 4 const int n = tokens.size(); 5 sort(tokens.begin(), tokens.end()); //1. sort 6 int points = 0, ret = 0; 7 //2 .2 pointers, boundary 8 int p1 = 0, p2 = n - 1; 9 while (p1 <= p2) { 10 int preP1 = p1, preP2 = p2; 11 while (p1 <= p2 && P >= tokens[p1]) { 12 points += 1; 13 P -= tokens[p1++]; 14 } 15 ret = max(points, ret); 16 if (p1 <= p2 && points >= 1) { 17 points -= 1; 18 P += tokens[p2--]; 19 } 20 if (p1 == preP1 && p2 == preP2) { 21 break; 22 } 23 } 24 return ret; 25 } 26 };
Contest 113 (2018年12月2日)(题号949~952)
比赛情况记录:结果:3/4, ranking: 708/3549。起床晚了,第一题手残调试点成提交,懵逼的WA了三次。第二题跟 symmetric tree 那个很像。第三题跟前几周周赛的第四题很像。第四题他们说是线性筛法求素数。
链接:https://leetcode.com/contest/weekly-contest-113
【949】Largest Time for Given Digits(第一题 4分)
给了一个数组里面四个整数(0-9),返回这个数组能生成的最大时间表示 HH:MM。
题解:暴力生成所有的排列,然后判断是否符合时间的定义,然后用ret变量标记最大的字符串。(时间相关的类似题:lc 681)
1 class Solution { 2 public: 3 string largestTimeFromDigits(vector<int>& A) { 4 sort(A.begin(), A.end()); 5 if (A[0] >= 3) {return "";} 6 string ret = ""; 7 do { 8 string str = string(1, A[0] + ‘0‘) + string(1, A[1] + ‘0‘) + ":" + string(1, A[2] + ‘0‘) + string(1, A[3] + ‘0‘); 9 if (isValid(str)) { 10 if (str > ret) { 11 ret = str; 12 } 13 } 14 } while(next_permutation(A.begin(), A.end())); 15 return ret; 16 } 17 bool isValid(string str) { 18 if (str[0] > ‘2‘) { return false;} 19 if (str[0] == ‘2‘ && str[1] >= ‘4‘) { return false; } 20 if (str[3] >= ‘6‘) { return false;} 21 return true; 22 } 23 };
【951】Flip Equivalent Binary Trees(第二题 5分)
For a binary tree T, we can define a flip operation as follows: choose any node, and swap the left and right child subtrees.
A binary tree X is flip equivalent to a binary tree Y if and only if we can make X equal to Y after some number of flip operations.
Write a function that determines whether two binary trees are flip equivalent. The trees are given by root nodes root1
and root2
.
题解:我先判断有没有根,有根但是值不相等的话,就返回false,递归判断 root1 的左儿子和 root2 的左儿子 以及 root1 的右儿子和 root2 的右儿子 是不是 FlipEqui,如果是直接返回yes。否则递归判断 root1 的右儿子和 root2 的左儿子 以及 root1 的左儿子和 root2 的右儿子 是不是 FlipEqui,是的话,返回yes。都不行就返回false。(类似题:lc 101)
1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10 class Solution { 11 public: 12 bool flipEquiv(TreeNode* root1, TreeNode* root2) { 13 if (!root1 && !root2) {return true;} 14 if (!root1 || !root2) {return false;} 15 if (root1->val != root2->val) {return false;} 16 bool res1 = flipEquiv(root1->left, root2->left) && flipEquiv(root1->right, root2->right); 17 if (res1) { 18 return res1; 19 } 20 bool res2 = flipEquiv(root1->left, root2->right) && flipEquiv(root1->right, root2->left); 21 if (res2) { 22 return res2; 23 } 24 return false; 25 } 26 };
【950】Reveal Cards In Increasing Order(第三题 5分)
我们有一个 N 张的 unique 纸牌,我们希望得到一个序列,按照下面步骤操作之后,从这个序列弹出的序列是完全排好序的。
(1)弹出最上面一张纸牌 A1。
(2)如果 A1 下面有纸牌 A2,把 A2 放到这叠纸牌的最下方。
依次循环做(1)(2)操作。
Example 1: Input: [17,13,11,2,3,5,7] Output: [2,13,3,11,5,17,7] Explanation: We get the deck in the order [17,13,11,2,3,5,7] (this order doesn‘t matter), and reorder it. After reordering, the deck starts as [2,13,3,11,5,17,7], where 2 is the top of the deck. We reveal 2, and move 13 to the bottom. The deck is now [3,11,5,17,7,13]. We reveal 3, and move 11 to the bottom. The deck is now [5,17,7,13,11]. We reveal 5, and move 17 to the bottom. The deck is now [7,13,11,17]. We reveal 7, and move 13 to the bottom. The deck is now [11,17,13]. We reveal 11, and move 17 to the bottom. The deck is now [13,17]. We reveal 13, and move 17 to the bottom. The deck is now [17]. We reveal 17. Since all the cards revealed are in increasing order, the answer is correct.
题解:先把数组排序好了之后,从小到大依次隔空插入。
1 class Solution { 2 public: 3 vector<int> deckRevealedIncreasing(vector<int>& deck) { 4 const int n = deck.size(); 5 sort(deck.begin(), deck.end()); 6 vector<int> ret(n, -1); 7 int gap = 1, k = 0; 8 while (k < n) { 9 for (int i = 0; i < n; ++i) { 10 if (ret[i] != -1) {continue;} 11 if (gap) { 12 ret[i] = deck[k]; 13 ++k; 14 gap = 0; 15 if (k >= n) {break;} 16 } else { 17 if (ret[i] == -1) {gap = 1;} 18 } 19 } 20 } 21 return ret; 22 } 23 };
【952】Largest Component Size by Common Factor (第四题 8分)
Contest 114(2018年12月9日)(题号953-956)
比赛情况记录:本周一直比较萎靡,唉,结果:2/4,ranking: 696 / 3198,我认为第三题第四题都不难,然而实现上有困难,肯定是我的问题了。
链接:https://leetcode.com/contest/weekly-contest-114
【953】Verifying an Alien Dictionary(第一题 4分)
有一种外星文字也包含 ‘a’ 到 ‘z‘ 26个字母,只不过字母顺序不一样罢了。给了一堆 words,判断这些 words 是不是按照外星字典顺序排列的。
题解:我用 unordered_map 存储了外星字母对应英文字母的关系,然后把每一个 word 转换成英文单词,看这些单词是否符合字典顺序。
1 class Solution { 2 public: 3 bool isAlienSorted(vector<string>& words, string order) { 4 //1. map relationship 5 unordered_map<char, char> mp; 6 for (int i = 0; i < 26; ++i) { 7 mp[order[i]] = i + ‘a‘; 8 } 9 //2. change word 10 vector<string> inputs = words; 11 for (auto& w : inputs) { 12 for (auto& c : w) { 13 c = mp[c]; 14 } 15 } 16 //3. check order 17 for (int i = 1; i < inputs.size(); ++i) { 18 if (inputs[i] < inputs[i-1]) { 19 return false; 20 } 21 } 22 return true; 23 } 24 };
【954】Array of Doubled Pairs(第二题 5分)
【955】Delete Columns to Make Sorted II(第三题 6分)
【956】Tallest Billboard(第四题 8分)
Contest 115(2018年12月16日)(题号957-960)
比赛情况记录:本周比赛马马虎虎吧,第四题不会做比较尴尬。结果: 2/4,ranking: 490/3055。第三题看了题真是没啥想法。第四题是个LIS的变种题(把一列看成一个元素,自己实现比较大小)。
链接:https://leetcode.com/contest/weekly-contest-115
【958】Check Completeness of a Binary Tree(第一题 5分)
检查一棵树是不是完全二叉树。
题解:第一题有稍微有点卡住了。有两种检测方法,都不是那么的直观。第一种是 dfs,判断是不是左右子树都是完全二叉树,然后判断左子树高度最多比右子树高度大一。第二种是 bfs,判断方法是
(1)如果当前结点有右孩子但是没有左孩子,那么直接返回false。
(2)如果当前结点不是左右孩子都有,那么后面的结点都必须是叶子结点。
1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10 class Solution { 11 public: 12 bool isCompleteTree(TreeNode* root) { 13 if (!root) {return true;} 14 queue<TreeNode*> que; 15 que.push(root); 16 bool mark = false; 17 while (!que.empty()) { 18 int size = que.size(); 19 for (int i = 0; i < size; ++i) { 20 TreeNode* cur = que.front(); que.pop(); 21 if (mark && (cur->left || cur->right)) { 22 return false; 23 } 24 if (cur->left) { 25 que.push(cur->left); 26 } 27 if (cur->right) { 28 que.push(cur->right); 29 } 30 if (cur->left && !cur->right || !cur->left && !cur->right) { 31 mark = true; 32 } 33 if (cur->right && !cur->left) { 34 return false; 35 } 36 } 37 } 38 return true; 39 } 40 };
【957】Prison Cells After N Days(第二题 6分)
有一个数组里面有 8 个0/1元素, 分别代表8个囚室,0代表囚室为空,1代表囚室有人。每天囚室的人员分布都在变化。变化规则就是如下两条:
- If a cell has two adjacent neighbors that are both occupied or both vacant, then the cell becomes occupied.
- Otherwise, it becomes vacant.
给了 Day 0 的囚室分布,问第 N 天的囚室分布。(1 <= N <= 10^9
)
题解:这题肯定是有循环节的。我们可以注意到第一个 cell 和最后一个 cell 肯定从第一天开始就都是 0 了,因为他们就没有两个邻居。然后中间的 6个 cell,它们要么是 0 要么是 1。所以循环节最多也就是 2^6 = 64 个排列。我们用个数组记录每个vector代表的二进制数。然后我们找循环节就行了。
1 class Solution { 2 public: 3 vector<int> prisonAfterNDays(vector<int>& cells, int N) { 4 int number = vector2Int(cells); 5 vector<int> array(256, -1); 6 vector<int> nCells = cells; 7 int day = 0; 8 do { 9 array[day++] = number; 10 number = transNextDay(nCells); 11 if (day == N + 1) { 12 break; 13 } 14 } while (find(array.begin(), array.end(), number) == array.end()); 15 if (day == N + 1) { 16 vector<int> ret = getVector(array[N]); 17 return ret; 18 } 19 auto iter = find(array.begin(), array.end(), number); 20 const int startDay = distance(array.begin(), iter); 21 const int cycle = day - startDay; 22 int idx = ((N - startDay) % cycle); 23 vector<int> ret = getVector(array[startDay + idx]); 24 return ret; 25 } 26 int vector2Int(const vector<int>& nums) { 27 int pow = 1, ret = 0; 28 for (int i = 0; i < 8; ++i) { 29 ret += pow * nums[i]; 30 pow *= 2; 31 } 32 return ret; 33 } 34 int transNextDay(vector<int>& nCells) { 35 vector<int> newCells(8, 0); 36 for (int i = 1; i < 8 -1; ++i) { 37 if (nCells[i-1] ^ nCells[i+1] == 0) { 38 newCells[i] = 1; 39 } 40 } 41 int ret = vector2Int(newCells); 42 nCells = newCells; 43 return ret; 44 } 45 vector<int> getVector(int num) { 46 vector<int> ret(8, 0); 47 for (int i = 0; i < 8; ++i) { 48 ret[i] = num % 2; 49 num /= 2; 50 } 51 return ret; 52 } 53 };
【959】Regions Cut By Slashes(第三题 7分)
【960】Delete Columns to Make Sorted III(第四题 7分)
给了一个字符串数组 A,A[i] 表示一个字符串,我们要从字符矩阵A中删除某几列字符,使得每个字符串都是符合字母序的 (every element (row) in lexicographicorder)。问最少删除几列。
题解:这个题目有点像是 LIS,但是比赛的时候没想出来,我想的是每行都 LIS,然后求出 min(LIS) = x,在[1, x]中二分求最大的k。但是其实不是这样想的,这样暴力解复杂度太高,又难写。本题事实上应该把每一列都看成 LIS 的一个元素,然后我们自己定义元素的大小比较关系就行了。时间复杂度是 O(m*m*n)
1 class Solution { 2 public: 3 int minDeletionSize(vector<string>& A) { 4 const int n = A.size(), m = A[0].size(); 5 vector<int> dp(m, 1); 6 int maxLen = 1; 7 for (int i = m - 2; i >= 0; --i) { 8 for (int j = i + 1; j < m; ++j) { 9 bool found = false; 10 for (int k = 0; k < n; ++k) { 11 if (A[k][i] > A[k][j]) { 12 found = true; 13 break; 14 } 15 } 16 if (!found) { 17 dp[i] = max(dp[i], dp[j] + 1); 18 maxLen = max(maxLen, dp[i]); 19 } 20 } 21 } 22 return m - maxLen; 23 } 24 };
Contest 116(2018年12月23日)(题号961-964)
链接:https://leetcode.com/contest/weekly-contest-116
比赛情况记录:结果: 1/4,ranking: 1745/2965. 这两天我也不知道怎么了,锻炼练不下去,题目不想做,唉。希望只是一时状态不好而已。
【961】N-Repeated Element in Size 2N Array(第一题 2分)
【962】Maximum Width Ramp(第二题 5分)
给了一个数组 A,想找一对 tuple (i, j),满足 i < j && A[i] <= A[j]. 找到gap间距最大的 i, j, 返回 max(gap) 。
题解:看了lee215的解答,他说用 decreasing stack。其实我到现在都没有彻底get到这个点在哪里。吐血了。
1 class Solution { 2 public: 3 int maxWidthRamp(vector<int>& A) { 4 const int n = A.size(); 5 stack<int> stk; 6 for (int i = 0; i < n; ++i) { 7 if (stk.empty() || A[stk.top()] > A[i]) { 8 stk.push(i); 9 } 10 } 11 int ret = 0; 12 for (int i = n-1; i > 0; --i) { 13 while (!stk.empty() && A[i] >= A[stk.top()]) { 14 printf("i = %d, stk.top() = %d, A[i] = %d, A[stk.top()] = %d ", i, stk.top(), A[i], A[stk.top()]); 15 ret = max(i - stk.top(), ret); 16 stk.pop(); 17 } 18 } 19 return ret; 20 } 21 };
【963】Minimum Area Rectangle II(第三题 5分)
【964】Least Operators to Express Number (第四题 9分)
Contest 117(2018年12月30日)(题号965-968)
比赛情况记录:今天早上爬起来看群主mock interview,然后回去睡了一个回笼觉,结果就实在起不来了。所以这次是比赛之后马上开的virtual,virtual结果: 3/4,ranking:495/2770.
【965】Univalued Binary Tree(第一题 3分)
给了一棵二叉树判断整棵数是不是所有结点都是一个值。保证至少有一个根结点。
题解:dfs 或者 bfs 随你喜欢。
1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10 class Solution { 11 public: 12 bool isUnivalTree(TreeNode* root) { 13 if (!root) {return true;} 14 const int value = root->val; 15 queue<TreeNode*> que; 16 que.push(root); 17 bool ret = true; 18 while (!que.empty()) { 19 auto cur = que.front(); que.pop(); 20 if (cur->val != value) { 21 ret = false; 22 break; 23 } 24 if (cur->left) { 25 que.push(cur->left); 26 } 27 if (cur->right) { 28 que.push(cur->right); 29 } 30 } 31 return ret; 32 } 33 34 };
【967】Numbers With Same Consecutive Differences(第二题 5分)
返回所有长度为 N 的非负整数,相邻两个数位的差的绝对值是 K。前缀 0 的数是非法的,所以不要包含前缀 0 的数,比如 01,0 本身是合法的。
题解:dfs。我写的比较唠叨了,这题还可以更简洁。简洁版本有待补充。
1 class Solution { 2 public: 3 vector<int> numsSameConsecDiff(int N, int K) { 4 vector<int> ret; 5 if (K == 0) { 6 string strMul = string(N, ‘1‘); 7 const int mul = stoi(strMul); 8 for (int i = 1; i <= 9; ++i) { 9 int number = i * mul; 10 ret.push_back(number); 11 } 12 if (N == 1) { 13 ret.push_back(0); 14 } 15 return ret; 16 } 17 for (int i = 1; i <= 9; ++i) { 18 string strNum = to_string(i); 19 dfs(strNum, N - 1, K, ret); 20 } 21 if (N == 1) { 22 ret.push_back(0); 23 } 24 return ret; 25 } 26 void dfs(string& strNum, int leftSize, const int K, vector<int>& ret) { 27 if (leftSize == 0) { 28 ret.push_back(stoi(strNum)); 29 return; 30 } 31 int back = strNum.back() - ‘0‘; 32 if (back + K <= 9) { 33 string strLastDigit = to_string(back + K); 34 string strNew = strNum + strLastDigit; 35 dfs(strNew, leftSize - 1, K, ret); 36 } 37 if (back - K >= 0) { 38 string strLastDigit = to_string(back - K); 39 string strNew = strNum + strLastDigit; 40 dfs(strNew, leftSize - 1, K, ret); 41 } 42 return; 43 } 44 45 };
【966】Vowel Spellchecker(第三题 6分)
给了一个单词表和一大堆 query,每次 query 给一个单词,问这个单词能不能通过给出的规则变成单词表里面的词。能的话,返回第一个单词表里面对应的单词。
规则一。query的单词本身就在单词表中。
规则二。query的单词通过更改大小写字母变换成单词表中单词。
规则三。query的单词通过更换元音字母变换成单词表中单词。(这个匹配大小写不敏感)
规则优先级按照一二三递减。
题解:我这题一开始超时了,后来翻了一下群记录,原来要把元音化成通配符,类似pattern那种感觉。
1 class Solution { 2 public: 3 vector<string> spellchecker(vector<string>& wordlist, vector<string>& queries) { 4 set<string> stWord(wordlist.begin(), wordlist.end()); 5 const int n = queries.size(); 6 vector<string> ret(n, ""); 7 set<char> stTemp = {‘a‘, ‘e‘, ‘i‘, ‘o‘, ‘u‘}; 8 stVowel = stTemp; 9 //build map 10 for (int idx = 0; idx < wordlist.size(); ++idx) { 11 string strNew = str2Lower(wordlist[idx]); 12 if (mp.find(strNew) == mp.end()) { 13 mp[strNew] = idx; 14 } 15 string s2 = str2Pattern(strNew); 16 if (mpVowels.find(s2) == mpVowels.end()) { 17 mpVowels[s2] = idx; 18 } 19 } 20 for (int i = 0; i < n; ++i) { 21 string w = queries[i]; 22 if (stWord.find(w) != stWord.end()) { //rule1 23 ret[i] = w; 24 } else if (mp.find(str2Lower(w)) != mp.end()) { //rule2 25 int idx = mp[str2Lower(w)]; 26 ret[i] = wordlist[idx]; 27 } else { //rule3 28 int idx = checkRule3(w); 29 if (idx == -1) { continue; } 30 ret[i] = wordlist[idx]; 31 } 32 } 33 return ret; 34 } 35 unordered_map<string, int> mp, mpVowels; 36 set<char> stVowel; 37 inline string str2Lower(string str) { 38 string strNew = str; 39 for (int i = 0; i < strNew.size(); ++i) { 40 if (isupper(strNew[i])) { 41 strNew[i] = tolower(strNew[i]); 42 } 43 } 44 return strNew; 45 } 46 inline string str2Pattern(string str) { 47 string strNew = str; 48 for (auto & c: strNew) { 49 if (stVowel.find(c) != stVowel.end()) { 50 c = ‘*‘; 51 } 52 } 53 return strNew; 54 } 55 int checkRule3 (string str) { 56 string strNew = str2Lower(str); 57 strNew = str2Pattern(strNew); 58 int ret = -1; 59 if (mpVowels.find(strNew) != mpVowels.end()) { 60 ret = mpVowels[strNew]; 61 } 62 return ret; 63 } 64 };
【968】Binary Tree Cameras(第四题 8分)
Contest 118(2019年1月6日)(题号969-972)
链接:https://leetcode.com/contest/weekly-contest-118
总结:rank 730/3587, 结果:2/4。 具体比赛的时候的想法已经忘没了,尴尬。噢,第二题我本来是想出来的,结果手残了还没看出来。
【970】Powerful Integers(第一题 3分)
给了两个非负整数,x 和 y, 以及一个数 bound,求表达式 x^i + y^j 中所有小于等于 bound 的值,用数组的形式返回。其中 i >= 0, j >= 0。
题解:直接暴力,注意 x = 1 和 y = 1 的时候怎么办。不要写死循环了。
1 class Solution { 2 public: 3 vector<int> powerfulIntegers(int x, int y, int bound) { 4 int curx = 1, cury = 1; 5 set<int> ret; 6 for (int i = 0; curx + cury <= bound; ++i) { 7 for (int j = 0; curx + cury <= bound; ++j) { 8 if (curx + cury <= bound) { 9 ret.insert(curx + cury); 10 } 11 cury *= y; 12 if (cury * y == cury) { 13 break; 14 } 15 } 16 if (curx * x == curx) { 17 break; 18 } 19 curx *= x; 20 cury = 1; 21 } 22 vector<int> ans; 23 for (auto s : ret) { 24 ans.push_back(s); 25 } 26 return ans; 27 } 28 };
【969】Pancake Sorting(第二题 5分)
煎饼排序,一次煎饼翻转的操作如下:我们可以选一个正整数 k,然后翻转前 k 个煎饼。输入是一个 A 数组,代表煎饼的大小,输出是一个 k 的数组,代表经过这个 k 数组的操作之后,A数组可以变成有序的。(k 的长度不超过 10 * A.size())
题解:我们可以考虑每次操作都使得一个煎饼放在最下方。可以这么操作,选出没有排序的数组中的最大煎饼,然后翻转一次,把最大的煎饼翻转到第一个位置,然后翻转整个没有排序的数组,把最大的煎饼从第一个位置换到最后一个位置。这样产生的 K 数组的大小是 2N。
1 class Solution { 2 public: 3 vector<int> pancakeSort(vector<int>& A) { 4 vector<int> copyA(A), ret; 5 sort(copyA.begin(), copyA.end()); 6 if (A == copyA) { 7 return ret; 8 } 9 n = A.size(); 10 flip(A, ret, n, copyA); 11 // print(A); 12 return ret; 13 } 14 void flip(vector<int>& A, vector<int>& ret, int cur, const vector<int> sortedA) { 15 if (cur == 1) { 16 return; 17 } 18 auto iter = find(A.begin(), A.end(), cur); 19 const int idx = distance(A.begin(), iter); 20 if (idx != 0) { 21 reverse(A.begin(), iter + 1); 22 // print(A); 23 ret.push_back(idx + 1); 24 } 25 if (A == sortedA) { 26 return; 27 } 28 reverse(A.begin(), A.begin() + cur); 29 // print(A); 30 ret.push_back(cur); 31 if (A == sortedA) { 32 return; 33 } 34 flip(A, ret, cur-1, sortedA); 35 } 36 void print(vector<int>& A) { 37 for (auto e : A) { 38 printf("%d ", e); 39 } 40 printf(" "); 41 } 42 int n; 43 };
【971】Flip Binary Tree To Match Preorder Traversal(第三题 6分)
【972】Equal Rational Numbers(第四题 8分)(第四题比赛的时候不会做,2019年1月17日算法群里的每日一题)
Contest 119(2019年1月13日)(题号973-976)
【973】K Closest Points to Origin(第一题 3分)
【976】Largest Perimeter Triangle(第二题 4分)
【974】Subarray Sums Divisible by K(第三题 6分)
【975】Odd Even Jump(第四题 8分)
以上是关于Leetcode周赛从contest-111开始。(一般是10个contest写一篇文章)的主要内容,如果未能解决你的问题,请参考以下文章
Leetcode周赛从contest-41开始。(一般是10个contest写一篇文章)
Leetcode周赛从contest-121开始。(一般是10个contest写一篇文章)