• 【LeetCode】2020-04 每日一题


    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 };
    View Code

    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)
    View Code

    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 };
    View Code

    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
    View Code

    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 };
    View Code

    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]
    View Code

    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 };
    View Code

    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
    View Code

    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 };
    View Code

    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
    View Code

    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 };
    View Code

    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
    View Code

    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 };
    View Code

    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
    View Code

    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 };
    View Code

    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;
    View Code

    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 };
    View Code

    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         
    View Code

    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 };
    View Code

    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
    View Code
  • 相关阅读:
    WebSocket
    Spring Web MVC
    对象关系映射(ORM)数据访问
    使用JDBC进行数据访问
    【Mysql】【基础综合题解】大一下学期数据库综合训练题解
    【Mysql】【解决问题】[Err] 1055
    【JavaSE】【IO流】复制单级或多级文件夹
    C#使用FFmpeg的总结
    C#一个IM系统简单总结
    重新开启博客
  • 原文地址:https://www.cnblogs.com/z1014601153/p/12731777.html
Copyright © 2020-2023  润新知