8. 字符串转换整数 (atoi)(中等)

【分类】:模拟、正则表达式

【题解】:

解法1:直接模拟,但是在判断INT_MAX和INT_MIN上需要注意,因为直接判断会超出范围,所以可以将式子转换一下,本来是num * 10 + str[i] - '0' > MAX,可以转换为(MAX - (stri[i] - '0')) / 10 < num。

解法2:不得不说正则表达式真的牛逼啊啊啊啊!!!

'^[\+\-]?\d+', s.lstrip()

让我们来分析一下这个关键部分!

^x:表示匹配以字符串x为开头的字符串

[\+\-]?:匹配+或-或者什么也没有(?表示将前面的字符匹配0或1次)

\d:表示数字

+:表示前面的字符一次或无数次

s.lstrip(a):将字符串前面连续的a字符去除,默认为‘ ’

肯定有人要问最前面的*是什么意思了!!这个是解包,可以将findall返回的列表组成一个字符串。

【代码】:

C++(解法1):

 1 class Solution {
2 public:
3 int myAtoi(string str) {
4 int i = 0, f = 0;
5 for (i = 0; i < str.size() && str[i] == ' '; i++);
6 if (str[i] == '-')f = -1, i++;
7 else if (str[i] == '+') f = 1, i++;
8 else if(isdigit(str[i]))f = 1;
9 if (f == 0)return 0;
10 int num = 0, f2 = 0;
11 int MAX = 2147483647, MIN = -2147483648;
12 for (; i < str.size() && isdigit(str[i]); i++)
13 {
14 if (num > ((MAX - (str[i] - '0')) / 10 ))
15 {
16 if (f == 1)return MAX;
17 else return MIN;
18 }
19 num = num * 10 + (str[i] - '0');
20 }
21 if (f == 1)return num;
22 else return -num;
23 }
24 };

Python3(解法2):

1 class Solution:
2 def myAtoi(self, s: str) -> int:
3 return max(min(int(*re.findall('^[\+\-]?\d+', s.lstrip())), 2**31 - 1), -2**31)

11. 盛最多水的容器(中等)

【分类】:双指针

【题解】:将指针l、r分别位于两端,比较两端元素大小,假如说左端大,那么易得以右端为端点已经取到了最大值(因为元素间距离不能再大了),我们接下来可以看看以左端为端点还能不能更大,所以要把右指针往左移,此时如果右端大,那么以左端为端点已经取得了最大值,依次类推。

【代码】:

C++:

 1 class Solution {
2 public:
3 int maxArea(vector<int>& height) {
4 int ans = 0, l = 0, r = height.size() - 1;
5 while(l <= r)
6 {
7 ans = max(ans, min(height[l], height[r]) * (r - l));
8 if (height[l] > height[r])r--;
9 else l++;
10 }
11 return ans;
12 }
13 };

Python3:

 1 class Solution:
2 def maxArea(self, height: List[int]) -> int:
3 ans = 0
4 l = 0
5 r = len(height) - 1
6 while l <= r:
7 ans = max(ans, min(height[l], height[r]) * (r - l))
8 if (height[l] > height[r]): r -= 1
9 else: l += 1
10 return ans

22. 括号生成(中等)

【分类】:dfs、动态规划

【题解】:

解法1:回溯法,l为剩余左括号数量,r为剩余右括号数量,先考虑递归出口,也就是l=0&r=0的时候return(没有剩余括号啦)。然后只要l还有剩余我们就可以一直递归下去,那么右括号什么情况可以递归呢,必须当r > l时才可以,比如n=2我现在是(),后面肯定不能再加)啦。

解法2:考虑n个括号的情况可以由n-1个括号的情况得到,假设第n个括号的左括号在最左,那么n个括号的情况就是这样了()a,(a),a就是前n-1个括号的情况。所以也可以统一为(p)q,p = [0, n - 1],q = n - 1 - p即可涵盖上述情况。

【代码】:

C++(解法1):

 1 class Solution {
2 public:
3 vector<string>ans;
4 vector<string> generateParenthesis(int n) {
5 dfs("", n, n);
6 return ans;
7 }
8 void dfs(string s, int l, int r)
9 {
10 if (l == 0 && r == 0)
11 {
12 ans.push_back(s);
13 return;
14 }
15 if (l > 0)
16 dfs(s + "(", l - 1, r);
17 if (r > l)
18 dfs(s + ")", l, r - 1);
19 return;
20 }
21 };

Python3(解法2):

 1 class Solution:
2 def generateParenthesis(self, n: int) -> List[str]:
3 dp = []
4 dp.append([""])
5 for i in range(1, n + 1):
6 cur = []
7 for j in range(i):
8 l = dp[j]
9 r = dp[i - 1 -j]
10 for ll in l:
11 for rr in r:
12 s = "(" + ll + ")" + rr
13 cur.append(s)
14 dp.append(cur)
15 return dp[n]

55. 跳跃游戏(中等)

【分类】:贪心

【题解】:

解法1:因为每个位置除0外最小能跳的距离为1,实际上只要考虑每个0的位置能否跳过即可,所以每当遍历到0的时候,再往前遍历查找是否有一个位置能够跳过0,只要能跳过所有的0位置,就一定能跳到终点。

解法2:维护一个当前可以跳到的最大距离值。

【代码】:

C++(解法1):

 1 class Solution {
2 public:
3 bool canJump(vector<int>& nums) {
4 for (int i = 0; i < nums.size() - 1; i++)
5 {
6 if (nums[i] == 0)
7 {
8 int f = 0;
9 int t = i + 1, j = i - 1;
10 while(j >= 0)
11 {
12 if (nums[j] >= t - j)
13 {
14 f = 1;
15 break;
16 }
17 j--;
18 }
19 if (!f)return false;
20 }
21 }
22 return true;
23 }
24 };

Python3(解法2):

1 class Solution:
2 def canJump(self, nums: List[int]) -> bool:
3 rightmost = 0
4 for i in range(len(nums)):
5 if rightmost >= i:
6 rightmost = max(rightmost, i + nums[i])
7 else:
8 return False
9 return True

56. 合并区间(中等)

【分类】:贪心

【题解】:每个区间按照左端点进行排序,然后遍历所有区间,当下一个区间的左端点大于当前区间的右端点说明这段区间不重合,反之说明重合,所以更新重合区间的右端点。

【代码】:

C++:

 1 struct Node{
2 int x, y;
3 };
4 class Solution {
5 public:
6 static bool cmp(Node a, Node b)
7 {
8 return a.x != b.x ? a.x < b.x : a.y < b.y;
9 }
10 vector<vector<int>> merge(vector<vector<int>>& intervals) {
11 vector<Node>v;
12 vector<vector<int> > ans;
13 for (int i = 0; i < intervals.size(); i++)
14 v.push_back({intervals[i][0], intervals[i][1]});
15 if (v.size() == 0)return ans;
16 sort(v.begin(), v.end(), cmp);
17 int l = v[0].x, r = v[0].y;
18 for (int i = 1; i < v.size(); i++)
19 {
20 if (v[i].x <= r) r = max(v[i].y, r);
21 else
22 {
23 vector<int>t;
24 t.push_back(l);
25 t.push_back(r);
26 ans.push_back(t);
27 l = v[i].x;
28 r = v[i].y;
29 }
30 }
31 vector<int>t;
32 t.push_back(l);
33 t.push_back(r);
34 ans.push_back(t);
35 return ans;
36 }
37 };

Python3:

 1 class Solution:
2 def merge(self, intervals: List[List[int]]) -> List[List[int]]:
3 if len(intervals) == 0:
4 return []
5 res = []
6 intervals.sort(key=lambda x: x[0])
7 for inter in intervals:
8 if len(res) == 0 or res[-1][1] < inter[0]:
9 res.append(inter)
10 else:
11 res[-1][1] = max(res[-1][1], inter[1])
12 return res

151. 翻转字符串里的单词(中等)

【分类】:字符串

【题解】:这种字符串的题用Python简直不要方便太多!!C++的话根据题意老老实实模拟就好啦。

【代码】:

C++:

 1 class Solution {
2 public:
3 string reverseWords(string s) {
4 vector<string>v;
5 string ss = "";
6 for (int i = 0; i < s.size(); i++)
7 {
8 if (s[i] != ' ')ss = ss + s[i];
9 else
10 {
11 if (ss != "")
12 {
13 v.push_back(ss);
14 ss = "";
15 }
16 }
17 }
18 if (ss != "")v.push_back(ss);
19 if (v.size() == 0)return "";
20 ss = "";
21 reverse(v.begin(), v.end());
22 for (int i = 0; i < v.size() - 1; i++)
23 ss = ss + v[i] + " ";
24 ss = ss + v[v.size() - 1];
25 return ss;
26 }
27 };

Python3:

1 class Solution:
2 def reverseWords(self, s: str) -> str:
3 ls = s.split(' ') # 按空格分隔单词
4 ls = list(filter(None, ls)) # 去除列表中的空字符串
5 ls.reverse() # 将列表倒序
6 ans = " ".join(ls)
7 return ans

199. 二叉树的右视图(中等)

【分类】:dfs、bfs、二叉树

【题解】:

解法1:bfs,维护一个数组d,d[i]表示深度为i的节点值,因为bfs是从左往右层序遍历,所以遍历过程中每个深度最后保存的值就是右视图看过去的值。

解法2:dfs,先遍历右子树,更新在每一层最先出现的元素即可。

【代码】:

C++(解法1):

 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 int ans[10005];
13 vector<int> rightSideView(TreeNode* root) {
14 queue<TreeNode*>q;
15 queue<int>d;
16 vector<int>v;
17 if (root == NULL)return v;
18 q.push(root);
19 d.push(0);
20 int maxdepth = 0;
21 while(!q.empty())
22 {
23 TreeNode* t = q.front();
24 q.pop();
25 int dd = d.front();
26 d.pop();
27 ans[dd] = t->val;
28 maxdepth = max(maxdepth, dd);
29 if (t->left != NULL)
30 {
31 q.push(t->left);
32 d.push(dd + 1);
33 }
34 if (t->right != NULL)
35 {
36 q.push(t->right);
37 d.push(dd + 1);
38 }
39 }
40 for(int i = 0; i <= maxdepth; i++)
41 v.push_back(ans[i]);
42 return v;
43 }
44 };

Python3(解法2):

 1 # Definition for a binary tree node.
2 # class TreeNode:
3 # def __init__(self, x):
4 # self.val = x
5 # self.left = None
6 # self.right = None
7
8 class Solution:
9 def dfs(self, root, depth):
10 if root == None: return
11 if depth > len(self.ans):
12 self.ans.append(root.val)
13 self.dfs(root.right, depth + 1)
14 self.dfs(root.left, depth + 1)
15 def rightSideView(self, root: TreeNode) -> List[int]:
16 self.ans = []
17 self.dfs(root, 1)
18 return self.ans

200. 岛屿数量(中等)

【分类】:dfs、bfs

【题解】:算是比较基础的搜索题吧,只写了dfs。一定要看清楚题目是字符啊!!我一直以为是数字,被坑了好久。

【代码】:

C++:

 1 class Solution {
2 public:
3 int dirx[4] = {0, 0, 1, -1};
4 int diry[4] = {1, -1, 0, 0};
5 void dfs(vector<vector<char>>& grid, int x, int y, int n, int m)
6 {
7 if (x < 0 || x >= n || y < 0 || y >= m || grid[x][y] == '0')
8 return;
9 grid[x][y] = '0';
10 for(int i = 0; i < 4; i++)
11 dfs(grid, x + dirx[i], y + diry[i], n, m);
12 return;
13 }
14 int numIslands(vector<vector<char>>& grid) {
15 int n = grid.size();
16 if (n == 0)return 0;
17 int m = grid[0].size();
18 int ans = 0;
19 for (int i = 0; i < n; i++)
20 {
21 for (int j = 0; j < m; j++)
22 {
23 if (grid[i][j] == '1')
24 {
25 ans++;
26 dfs(grid, i, j, n, m);
27 }
28 }
29 }
30 return ans;
31 }
32 };

Python3:

 1 class Solution:
2 def __init__(self):
3 self.dire = [(0, 1), (0, -1), (1, 0), (-1, 0)]
4 def dfs(self, grid, x, y, n, m):
5 if x < 0 or x >= n or y < 0 or y >= m or grid[x][y] == '0':
6 return
7 grid[x][y] = '0'
8 for d in self.dire:
9 self.dfs(grid, x + d[0], y + d[1], n, m)
10 def numIslands(self, grid: List[List[str]]) -> int:
11 n = len(grid)
12 if n == 0: return 0
13 m = len(grid[0])
14 ans = 0
15 for i in range(n):
16 for j in range(m):
17 if grid[i][j] == '1':
18 ans += 1
19 self.dfs(grid, i, j, n, m)
20 return ans;

289. 生命游戏(中等)

【分类】:模拟、位运算

【题解】:

解法1:直接模拟,因为要求必须同时进行,所以只要将更新后的状态赋值给另一个数组,等更新完后再赋值回去就可以啦。

解法2:位运算。这个操作还是挺有意思的,反正我想不出来。现在我们用二进制表示每个格子细胞的状态(低位为之前的状态,高位为后来的状态):

(0)00:表示刚开始死的,后来还是死的

(1)01:表示刚开始活的,后来死了

(2)10:表示刚开始死的,后来活了

(3)11:表示刚开始活的,后来还是活的

然后分析一下条件可以发现:

1、当细胞是活的,周围有2或3个活细胞时可以活,对应上面的第(3)种情况

2、当细胞是死的,周围有3个活细胞时可以活,对应上面的第(2)种情况

所以每当满足以上两个条件的时候,如果是活细胞就记为3,死细胞就记为2。那么怎样计数呢?由于之前的状态在低位,所以只要每个状态&1就是本身的状态。

由于后来的状态在高位,那么最后的答案就是所有状态右移一位啦。

【代码】:

C++:

 1 class Solution {
2 public:
3 int t[505][505];
4 int dirx[8] = {0, 0, 1, 1, 1, -1, -1, -1};
5 int diry[8] = {1, -1, 0, 1, -1, 0, 1, -1};
6 void gameOfLife(vector<vector<int>>& board) {
7 int n = board.size();
8 if (n == 0)return;
9 int m = board[0].size();
10 for (int i = 0; i < n; i++)
11 {
12 for (int j = 0; j < m; j++)
13 {
14 int num1 = 0;
15 for(int ii = 0; ii < 8; ii++)
16 {
17 int x = i + dirx[ii];
18 int y = j + diry[ii];
19 if (x >= 0 && x < n && y >=0 && y < m && board[x][y])
20 num1++;
21 }
22 if (board[i][j] == 0)
23 {
24 if(num1 == 3)t[i][j] = 1;
25 else t[i][j] = 0;
26 }
27 else
28 {
29 if(num1 == 2 || num1 == 3)t[i][j] = 1;
30 else t[i][j] = 0;
31 }
32 }
33 }
34 for (int i = 0; i < n; i++)
35 for (int j = 0; j < m; j++)
36 board[i][j] = t[i][j];
37 }
38 };

Python3:

 1 class Solution:
2 def __init__(self):
3 self.dire = [(0, 1), (0, -1), (1, 0), (-1, 0), (1, 1), (1, -1), (-1, 1), (-1, -1)]
4 def gameOfLife(self, board: List[List[int]]) -> None:
5 n = len(board)
6 if n == 0: return
7 m = len(board[0])
8 for i in range(n):
9 for j in range(m):
10 num1 = 0
11 for d in self.dire:
12 x = i + d[0]
13 y = j + d[1]
14 if x >= 0 and x < n and y >= 0 and y < m:
15 num1 += board[x][y] & 1
16 if board[i][j] == 0 and num1 == 3:
17 board[i][j] = 2
18 elif board[i][j] == 1 and num1 in [2, 3]:
19 board[i][j] = 3
20 for i in range(n):
21 for j in range(m):
22 board[i][j] >>= 1
23

445. 两数相加 II(中等)

【分类】:栈、链表

【题解】:倒序首先就要想到栈啦,把两个链表的数据分别存入两个栈中,再依次取出相加即可,比忘了进位哦。

【代码】:

C++:

 1 /**
2 * Definition for singly-linked list.
3 * struct ListNode {
4 * int val;
5 * ListNode *next;
6 * ListNode(int x) : val(x), next(NULL) {}
7 * };
8 */
9 class Solution {
10 public:
11 ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
12 stack<int> s1, s2;
13 while(l1 != NULL)
14 {
15 s1.push(l1->val);
16 l1 = l1->next;
17 }
18 while(l2 != NULL)
19 {
20 s2.push(l2->val);
21 l2 = l2->next;
22 }
23 int c = 0;
24 ListNode* ans = NULL;
25 while(!s1.empty() || !s2.empty() || c != 0)
26 {
27 int t1 = s1.empty() ? 0: s1.top();
28 int t2 = s2.empty() ? 0: s2.top();
29 if(!s1.empty())s1.pop();
30 if(!s2.empty())s2.pop();
31 int t = t1 + t2 + c;
32 int now = t % 10;
33 c = t / 10;
34 ListNode* cur = new ListNode();
35 cur->val = now;
36 cur->next = ans;
37 ans = cur;
38 }
39 return ans;
40 }
41 };

Python3:

 1 # Definition for singly-linked list.
2 # class ListNode:
3 # def __init__(self, x):
4 # self.val = x
5 # self.next = None
6
7 class Solution:
8 def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
9 s1 = []
10 s2 = []
11 while(l1):
12 s1.append(l1.val)
13 l1 = l1.next
14 while(l2):
15 s2.append(l2.val)
16 l2 = l2.next
17 c = 0
18 ans = None
19 while(s1 or s2 or c != 0):
20 t1 = 0 if not s1 else s1.pop()
21 t2 = 0 if not s2 else s2.pop()
22 t = t1 + t2 + c
23 now = t % 10
24 c = t // 10
25 cur = ListNode(now)
26 cur.next = ans
27 ans = cur
28 return ans

【LeetCode】2020-04 每日一题的更多相关文章

  1. 【LeetCode】2020-03 每日一题

    121. 买卖股票的最佳时机(简单) [分类]:模拟.思维 [题解]:可以用O(n)的复杂度完成,只需要在遍历的时候记录到当前位置为止买入股票的最小价格minn,再维护一个当前卖出股票价(a-minn ...

  2. 【js】Leetcode每日一题-制作m束花所需的最少天数

    [js]Leetcode每日一题-制作m束花所需的最少天数 [题目描述] 给你一个整数数组 bloomDay,以及两个整数 m 和 k . 现需要制作 m 束花.制作花束时,需要使用花园中 相邻的 k ...

  3. 【JavaScript】Leetcode每日一题-在D天内送包裹的能力

    [JavaScript]Leetcode每日一题-在D天内送包裹的能力 [题目描述] 传送带上的包裹必须在 D 天内从一个港口运送到另一个港口. 传送带上的第 i 个包裹的重量为 weights[i] ...

  4. 【js】Leetcode每日一题-完成所有工作的最短时间

    [js]Leetcode每日一题-完成所有工作的最短时间 [题目描述] 给你一个整数数组 jobs ,其中 jobs[i] 是完成第 i 项工作要花费的时间. 请你将这些工作分配给 k 位工人.所有工 ...

  5. 【js】Leetcode每日一题-数组异或操作

    [js]Leetcode每日一题-数组异或操作 [题目描述] 给你两个整数,n 和 start . 数组 nums 定义为:nums[i] = start + 2*i(下标从 0 开始)且 n == ...

  6. 【js】Leetcode每日一题-解码异或后数组

    [js]Leetcode每日一题-解码异或后数组 [题目描述] 未知 整数数组 arr 由 n 个非负整数组成. 经编码后变为长度为 n - 1 的另一个整数数组 encoded ,其中 encode ...

  7. 【JavaScript】Leetcode每日一题-青蛙过河

    [JavaScript]Leetcode每日一题-青蛙过河 [题目描述] 一只青蛙想要过河. 假定河流被等分为若干个单元格,并且在每一个单元格内都有可能放有一块石子(也有可能没有). 青蛙可以跳上石子 ...

  8. 【JavaScript】Leetcode每日一题-平方数之和

    [JavaScript]Leetcode每日一题-平方数之和 [题目描述] 给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a2 + b2 = c . 示例1: 输入:c = 5 ...

  9. 【JavaScript】Leetcode每日一题-二叉搜索树的范围和

    [JavaScript]Leetcode每日一题-二叉搜索树的范围和 [题目描述] 给定二叉搜索树的根结点 root,返回值位于范围 [low, high] 之间的所有结点的值的和. 示例1: 输入: ...

随机推荐

  1. HDU4565-数学推导求递推公式+矩阵快速幂

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4565 我们带着这个根号是没法计算的 我们仔细观察一下,(a+sqrt(b))^n用二项式定理展开,我 ...

  2. Keras 报错: Error when checking target: expected dense_4...

    笔者此处是一个回归任务, 最后一层是: ... pred = Dense(1)(x) 在最后一个Dense层前加上x = Flatten()(x)即可.

  3. Dell Display Manager for Mac

    Dell Display Manager for Mac DDM for macOS solution https://www.dell.com/community/Monitors/DDM-for- ...

  4. how to check SVG type in js

    how to check SVG type in js SVGSVGElement & SVGElement svg = document.querySelector(`svg`); // & ...

  5. TDD & Unit testing

    TDD & Unit testing TDD jest https://github.com/facebook/jest https://facebook.github.io/jest/zh- ...

  6. DOH & TRR & HTTPS & DNS

    DOH & TRR & HTTPS & DNS DNS over HTTPS Trusted Recursive Resolver DNS 解析过程图解 DNS 解析过程 递归 ...

  7. HTML5 in depth

    HTML5 in depth Content Models Web Storage web storage 存储用户信息, 替代 cookies LocalStorage SessionStorage ...

  8. taro 三端开发

    taro 三端开发 wx 小程序, alipay 小程序,H5 https://taro-docs.jd.com/taro/docs/GETTING-STARTED.html#h5 https://t ...

  9. nasm astrcspn函数 x86

    xxx.asm %define p1 ebp+8 %define p2 ebp+12 %define p3 ebp+16 section .text global dllmain export ast ...

  10. K8s炼气期(一)| minikube安装本地Kubenetes环境

    前言 根据Kubenetes学习路径的七大阶段,炼气期.筑基期.金丹期.元婴期.化神期.炼虚期.大乘期:开始炼气期的第一个小阶段,安装Kubenetes环境. 目录 1.安装kubectl 2.安装m ...