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. OAuth2授权流程

  2. 攻防世界ctf bug

    bug 考查: 逻辑漏洞.文件内容检测绕过 ,文件头是位于文件开头的一段承担一定任务的数据,一般开头标记文件类型,如gif的gif89a,或gif87a, png的x89PNG\x0d\x0a,等等 ...

  3. XSS脚本汇总

    (1)普通的XSS JavaScript注入<SCRIPT SRC=http://***/XSS/xss.js></SCRIPT> (2)IMG标签XSS使用JavaScrip ...

  4. 101道Numpy、Pandas练习题

    无论是数据分析还是机器学习,数据的预处理必不可少. 其中最常用.最基础的Python库非numpy和pandas莫属,很多初学者可能看了很多教程,但是很快就把用法忘光了. 光看不练假把式,今天向大家推 ...

  5. Ajax & JSONP 原理

    Ajax & JSONP 原理 AJAX不是JavaScript的规范,它只是一个哥们"发明"的缩写:Asynchronous JavaScript and XML,意思就 ...

  6. taro 三端开发

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

  7. Flutter ColorFiltered 将ColorFilter应用于其子级。

    ColorFiltered ColorFilter BlendMode Example <summary>main.dart</summary> import 'package ...

  8. Flutter: moor_flutter库,简化sqlite操作

    入门 video moor_flutter 示例代码仓库 install dependencies: ... moor_flutter: dev_dependencies: ... moor_gene ...

  9. 千万不要错过VAST,NGK算力的下一个财富机会!

    我们把目光投向NGK市场,近来,NGK接连新币,推出了SPC后,又有VAST.在目前市场上债券收益率已经趋近于零的情况下,世界上的大多数央行都在试图让本国货币贬值,所以在此时寻找其他保值资产是合理的. ...

  10. NGK公链:通用型存储网络

    NGK公链,是一条发展中的通用型存储网络. NGK的运用归结与存储场景.NGK通证的运用归结于支付场景.个人数据被中心化服务商买卖.被大数据服务商使用.被无数的商务及销售人员窃取.那么NGK的运用场景 ...