LeetCode每周末举办比赛,这是今天上午比赛的题解。
1. Add Strings (LeetCode 415 Easy)
Given two non-negative numbers num1
and num2
represented as string, return the sum of num1
and num2
.
Note:
- The length of both
num1
andnum2
is < 5100. - Both
num1
andnum2
contains only digits0-9
. - Both
num1
andnum2
does not contain any leading zero. - You must not use any built-in BigInteger library or convert the inputs to integer directly.
分析:
就是把字符串做加减,参考之前做过的带进位的题,写while循环用三者 ||写起来比较简洁。
然而在处理字符串那里除了点问题,应该写char的地方一直用的“”,导致调了一会儿bug。
代码:
1 class Solution { 2 public: 3 string addStrings(string num1, string num2) { 4 int i = num1.size() - 1, j = num2.size() - 1, carry = 0; 5 string result; 6 while (i >= 0 || j >= 0 || carry > 0) { 7 int temp = 0; 8 if (i >= 0) { 9 temp += (num1[i] - '0'); 10 i--; 11 } 12 if (j >= 0) { 13 temp += (num2[j] - '0'); 14 j--; 15 } 16 temp += carry; 17 if (temp >= 10) { 18 carry = 1; 19 temp -= 10; 20 result = char(temp + '0') + result; 21 } 22 else { 23 carry = 0; 24 result = char(temp + '0') + result; 25 } 26 } 27 return result; 28 } 29 };
2. Partition Equal Subset Sum (LeetCode 416 Medium)
Given a non-empty array containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal.
Note:
Both the array size and each of the array element will not exceed 100.
Example 1:
Input: [1, 5, 11, 5] Output: true Explanation: The array can be partitioned as [1, 5, 5] and [11].
Example 2:
Input: [1, 2, 3, 5] Output: false Explanation: The array cannot be partitioned into equal sum subsets.
分析:
用01背包的思路,bool值 dp[i][j] 表示从0,1,2...i选重量为j是否可能。
则有递推关系:
dp[i][j] = dp[i - 1][j] || dp[i][j - nums[i]]; (i位置取或者不取)
结果返回值为dp[nums.size() - 1][sum]; (sum为和的一半)
代码:
1 class Solution { 2 public: 3 bool canPartition(vector<int>& nums) { 4 int sum = 0; 5 for (int i = 0; i < nums.size(); ++i) { 6 sum += nums[i]; 7 } 8 if (sum % 2 == 1) { 9 return false; 10 } 11 sum /= 2; 12 int dp[nums.size()][sum] = {false}; 13 if (nums.size() == 1) { 14 return false; 15 } 16 for (int i = 0; i <= sum; ++i) { 17 if (nums[0] == i) { 18 dp[0][i] = true; 19 } 20 } 21 for (int i = 1; i < nums.size(); ++i) { 22 for (int j = 1; j <= sum; ++j) { 23 dp[i][j] = dp[i - 1][j] || dp[i][j - nums[i]]; 24 } 25 } 26 return dp[nums.size() - 1][sum]; 27 } 28 };
3. Pacific Atlantic Water Flow (LeetCode 417 Medium)
Given an m x n
matrix of non-negative integers representing the height of each unit cell in a continent, the "Pacific ocean" touches the left and top edges of the matrix and the "Atlantic ocean" touches the right and bottom edges.
Water can only flow in four directions (up, down, left, or right) from a cell to another one with height equal or lower.
Find the list of grid coordinates where water can flow to both the Pacific and Atlantic ocean.
Note:
- The order of returned grid coordinates does not matter.
- Both m and n are less than 150.
Example:
Given the following 5x5 matrix: Pacific ~ ~ ~ ~ ~ ~ 1 2 2 3 (5) * ~ 3 2 3 (4) (4) * ~ 2 4 (5) 3 1 * ~ (6) (7) 1 4 5 * ~ (5) 1 1 2 4 * * * * * * Atlantic Return: [[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]] (positions with parentheses in above matrix).
分析:
深搜加上记忆化搜索的思路。对于每个点搜索其能否到达两个海洋,并将结果记录在两个数组中以备后续搜索时使用。
dp用来进行记忆化搜索,flag用来进行节点判重,不死循环。
代码:
1 class Solution { 2 private: 3 int dp1[155][155]; 4 int dp2[155][155]; 5 int flag1[155][155]; 6 int flag2[155][155]; 7 int dx[4] = {-1,0,0,1}; 8 int dy[4] = {0,1,-1,0}; 9 bool isReachPac(int x, int y, const vector<vector<int>>& matrix) { 10 flag1[x][y] = 1; 11 if (dp1[x][y] == 1) { 12 return true; 13 } 14 if (x == 0 || y == 0) { 15 return true; 16 } 17 for (int i = 0; i < 4; ++i) { 18 int nx = x + dx[i]; 19 int ny = y + dy[i]; 20 if (nx >= 0 && ny >= 0 && nx < matrix.size() && ny < matrix[0].size() 21 && matrix[nx][ny] <= matrix[x][y] && flag1[nx][ny] != 1 && isReachPac(nx,ny,matrix) ) { 22 dp1[x][y] = 1; 23 return true; 24 } 25 } 26 return false; 27 } 28 bool isReachAtl(int x, int y, const vector<vector<int>>& matrix) { 29 flag2[x][y] = 1; 30 if (dp2[x][y] == 1) { 31 return true; 32 } 33 if (x == matrix.size() - 1 || y == matrix[0].size() - 1) { 34 return true; 35 } 36 for (int i = 0; i < 4; ++i) { 37 int nx = x + dx[i]; 38 int ny = y + dy[i]; 39 if (nx >= 0 && ny >= 0 && nx < matrix.size() && ny < matrix[0].size() 40 && matrix[nx][ny] <= matrix[x][y] && flag2[nx][ny] != 1 && isReachAtl(nx,ny,matrix) ) { 41 dp2[x][y] = 1; 42 return true; 43 } 44 } 45 return false; 46 } 47 public: 48 vector<pair<int, int>> pacificAtlantic(vector<vector<int>>& matrix) { 49 vector<pair<int, int>> result; 50 for (int i = 0; i < matrix.size(); ++i) { 51 for (int j = 0; j < matrix[0].size(); ++j) { 52 memset(flag1,0,sizeof(flag1)); 53 memset(flag2,0,sizeof(flag2)); 54 if(isReachPac(i,j,matrix) && isReachAtl(i,j,matrix)) { 55 result.push_back(make_pair(i,j)); 56 } 57 } 58 } 59 return result; 60 } 61 };
4. Sentence Screen Fitting (LeetCode 418 Hard)
Given a rows x cols
screen and a sentence represented by a list of words, find how many times the given sentence can be fitted on the screen.
Note:
- A word cannot be split into two lines.
- The order of words in the sentence must remain unchanged.
- Two consecutive words in a line must be separated by a single space.
- Total words in the sentence won't exceed 100.
- Length of each word won't exceed 10.
- 1 ≤ rows, cols ≤ 20,000.
Example 1:
Input: rows = 2, cols = 8, sentence = ["hello", "world"] Output: 1 Explanation: hello--- world--- The character '-' signifies an empty space on the screen.
Example 2:
Input: rows = 3, cols = 6, sentence = ["a", "bcd", "e"] Output: 2 Explanation: a-bcd- e-a--- bcd-e- The character '-' signifies an empty space on the screen.
Example 3:
Input: rows = 4, cols = 5, sentence = ["I", "had", "apple", "pie"] Output: 1 Explanation: I-had apple pie-I had-- The character '-' signifies an empty space on the screen.
分析:
题意就是给定句子在规定长宽的屏幕内能显示几次。
思路还是比较直观,就是按照单词显示的规则(词见空格,句子结束空格,行末则不空格等)计算在规定行列情况下的显示次数。
主要考察的就是如何提高效率过大一点的样例。
可以采用先将sentence内所有单词和空格的长度加起来,记录为senSize。
如果一行中剩余长度大于senSize时,直接result += tempC / senSize;tempC -= (tempC / senSize)* senSize; (tempC表示该行剩余未使用部分);
这样该行剩余部分不够显示一次sentence,再按之前的规则处理,可以AC。
代码:
1 class Solution { 2 public: 3 int wordsTyping(vector<string>& sentence, int rows, int cols) { 4 int senSize = 0; 5 for (int i = 0; i < sentence.size(); ++i) { 6 senSize += (sentence[i].size() + 1); 7 } 8 int result = 0, tempC = cols, flag = 0; 9 while (rows > 0) { 10 if (tempC > senSize) { 11 int inc = tempC / senSize; 12 result += inc; 13 tempC -= inc * senSize; 14 } 15 else { 16 for (int i = 0; i < sentence.size(); ++i) { 17 if (rows <= 0) { 18 flag = 1; 19 break; 20 } 21 if (sentence[i].size() > tempC) { 22 rows--; 23 tempC = cols; 24 i--; 25 } 26 else if (sentence[i].size() == tempC) { 27 rows--; 28 tempC = cols; 29 } 30 else { 31 tempC -= (sentence[i].size() + 1); 32 } 33 } 34 if (flag == 0) { 35 result++; 36 } 37 } 38 } 39 return result; 40 } 41 };
总体来讲这次的题目应该比之前做的一次简单,自己在第一个字符串处理那里调了半天bug,语言级问题,重视基础啊。
hard题比之前的来的简单,只需要稍作优化就可以accept。(然而被实验室的叫去吃饭,这个题当时没做出来。。。)