学习平台 AcWing LeetCode究极班
LeetCode
Let 1:两数之和 给定一个整数数组nums
和一个整数目标值target
,请你在该数组中找出和为目标值 target
的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例 1:
1 2 3 输入:nums = [2,7,11,15], target = 9 输出:[0,1] 解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
1 2 输入:nums = [3,2,4], target = 6 输出:[1,2]
示例 3:
1 2 输入:nums = [3,3], target = 6 输出:[0,1]
提示:
2 <= nums.length <= 104
109 <= nums[i] <= 109
109 <= target <= 109
只会存在一个有效答案
进阶: 你可以想出一个时间复杂度小于 O(n^2)
的算法吗?
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution {public : vector<int > twoSum (vector<int >& nums, int target) { vector<int > arr; for (int i=0 ;i < nums.size () - 1 ; i++){ for (int j = i + 1 ;j< nums.size (); j++){ if (nums[i]+nums[j] == target){ arr.push_back (i); arr.push_back (j); break ; } } } return arr; } };
Let 2:两数相加 给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例 1:
1 2 3 输入:l1 = [2,4,3], l2 = [5,6,4] 输出:[7,0,8] 解释:342 + 465 = 807.
示例 2:
1 2 输入:l1 = [0], l2 = [0] 输出:[0]
示例 3:
1 2 输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9] 输出:[8,9,9,9,0,0,0,1]
提示:
每个链表中的节点数在范围 [1, 100]
内
0 <= Node.val <= 9
题目数据保证列表表示的数字不含前导零
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution {public : ListNode* addTwoNumbers (ListNode* l1, ListNode* l2) { auto dummy = new ListNode (-1 ); auto cur = dummy; int t = 0 ; while (l1 || l2 || t){ if (l1) t += l1 -> val, l1 = l1 -> next; if (l2) t += l2 -> val, l2 = l2 -> next; cur -> next = new ListNode (t % 10 ); cur = cur -> next; t /= 10 ; } return dummy -> next; } };
Let 3:无重复字符的最长子串 给定一个字符串 s
,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
1 2 3 输入: s = "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
1 2 3 输入: s = "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
1 2 3 4 输入: s = "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
提示:
0 <= s.length <= 5 * 104
s
由英文字母、数字、符号和空格组成
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 class Solution {public : int lengthOfLongestSubstring (string s) { unordered_map<char , int > head; int res = 0 ; for (int i = 0 , j = 0 ; i < s.length (); i ++){ head[s[i]]++; while (head[s[i]] > 1 ) head[s[j++]]--; res = max (res, i - j + 1 ); } return res; } };
Let 4:寻找两个正序数组的中位数 给定两个大小分别为 m
和 n
的正序(从小到大)数组 nums1
和 nums2
。请你找出并返回这两个正序数组的 中位数 。
算法的时间复杂度应该为 O(log (m+n))
。
示例 1:
1 2 3 输入:nums1 = [1,3], nums2 = [2] 输出:2.00000 解释:合并数组 = [1,2,3] ,中位数 2
示例 2:
1 2 3 输入:nums1 = [1,2], nums2 = [3,4] 输出:2.50000 解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
提示:
nums1.length == m
nums2.length == n
0 <= m <= 1000
0 <= n <= 1000
1 <= m + n <= 2000
-106 <= nums1[i], nums2[i] <= 106
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution {public : double findMedianSortedArrays (vector<int >& nums1, vector<int >& nums2) { vector<double > arr; int i = 0 , j = 0 ; while (i < nums1.size () && j < nums2.size ()){ if (nums1[i] <= nums2[j]) arr.push_back (nums1[i++]); else arr.push_back (nums2[j++]); } while (i < nums1.size ()) arr.push_back (nums1[i++]); while (j < nums2.size ()) arr.push_back (nums2[j++]); int len = arr.size (); for (int k = 0 ; k < arr.size (); k++) cout << arr[k] << " " ; if (len % 2 != 0 ){ return arr[len / 2 ]; } else { return (arr[len / 2 ] + arr[len / 2 - 1 ]) / 2 ; } } };
Let 5:最长回文子串 * 给你一个字符串 s
,找到 s
中最长的回文子串。
示例 1:
1 2 3 输入:s = "babad" 输出:"bab" 解释:"aba" 同样是符合题意的答案。
示例 2:
提示:
1 <= s.length <= 1000
s 仅由数字和英文字母组成
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution {public : string longestPalindrome (string s) { string res; for (int i=0 ;i<s.size ();i++){ int l = i - 1 , r = i + 1 ; while (l >= 0 && r <= s.size () && s[l] == s[r]) l --, r ++; if (res.size () < r - l - 1 ) res = s.substr (l + 1 , r - l - 1 ); l = i, r = i + 1 ; while (l >= 0 && r <= s.size () && s[l] == s[r]) l --, r ++; if (res.size () < r - l -1 ) res = s.substr (l + 1 , r - l -1 ); } return res; } };
Let 6:Z 字形变换 将一个给定字符串 s
根据给定的行数 numRows
,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 "PAYPALISHIRING"
行数为 3
时,排列如下:
1 2 3 P A H N A P L S I I G Y I R
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"
。
请你实现这个将字符串进行指定行数变换的函数:
1 string convert(string s, int numRows);
示例 1:
1 2 输入:s = "PAYPALISHIRING", numRows = 3 输出:"PAHNAPLSIIGYIR"
示例 2:
1 2 3 4 5 6 7 输入:s = "PAYPALISHIRING", numRows = 4 输出:"PINALSIGYAHRPI" 解释: P I N A L S I G Y A H R P I
示例 3:
1 2 输入:s = "A", numRows = 1 输出:"A"
提示:
1 <= s.length <= 1000
s
由英文字母(小写和大写)、','
和 '.'
组成
1 <= numRows <= 1000
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution {public : string convert (string s, int n) { string res; if (n == 1 ) return s; for (int i = 0 ; i < n; i ++ ) { if (i == 0 || i == n - 1 ) { for (int j = i; j < s.size (); j += 2 * n - 2 ) res += s[j]; } else { for (int j = i, k = 2 * n - 2 - i; j < s.size () || k < s.size (); j += 2 * n - 2 , k += 2 * n - 2 ) { if (j < s.size ()) res += s[j]; if (k < s.size ()) res += s[k]; } } } return res; } };
Let 7:整数反转 给你一个 32 位的有符号整数 x
,返回将 x
中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1]
,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
示例 1:
示例 2:
示例 3:
示例 4:
提示:
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Solution {public : int reverse (int x) { if (x >= -9 && x <= 9 ) return x; long long ans = 0 ; while (x){ ans = ans * 10 + x % 10 ; if (ans < -2147483648 || ans > 2147483647 ){ return 0 ; } x /= 10 ; } return ans; } };
Let 8:字符串转换整数(atoi) * 请你来实现一个 myAtoi(string s)
函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi
函数)。
函数 myAtoi(string s)
的算法如下:
读入字符串并丢弃无用的前导空格
检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。
读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
将前面步骤读入的这些数字转换为整数(即,”123” -> 123, “0032” -> 32)。如果没有读入数字,则整数为0
。必要时更改符号(从步骤 2 开始)。
如果整数数超过 32 位有符号整数范围 [−231, 231 − 1]
,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231
的整数应该被固定为 −231
,大于 231 − 1
的整数应该被固定为 231 − 1
。
返回整数作为最终结果。
注意:
本题中的空白字符只包括空格字符' '
。
除前导空格或数字后的其余字符串外,请勿忽略 任何其他字符。
示例 1:
1 2 3 4 5 6 7 8 9 10 11 输入:s = "42" 输出:42 解释:加粗的字符串为已经读入的字符,插入符号是当前读取的字符。 第 1 步:"42"(当前没有读入字符,因为没有前导空格) ^ 第 2 步:"42"(当前没有读入字符,因为这里不存在 '-' 或者 '+') ^ 第 3 步:"42"(读入 "42") ^ 解析得到整数 42 。 由于 "42" 在范围 [-231, 231 - 1] 内,最终结果为 42 。
示例 2:
1 2 3 4 5 6 7 8 9 10 11 输入:s = " -42" 输出:-42 解释: 第 1 步:" -42"(读入前导空格,但忽视掉) ^ 第 2 步:" -42"(读入 '-' 字符,所以结果应该是负数) ^ 第 3 步:" -42"(读入 "42") ^ 解析得到整数 -42 。 由于 "-42" 在范围 [-231, 231 - 1] 内,最终结果为 -42 。
示例 3:
1 2 3 4 5 6 7 8 9 10 11 输入:s = "4193 with words" 输出:4193 解释: 第 1 步:"4193 with words"(当前没有读入字符,因为没有前导空格) ^ 第 2 步:"4193 with words"(当前没有读入字符,因为这里不存在 '-' 或者 '+') ^ 第 3 步:"4193 with words"(读入 "4193";由于下一个字符不是一个数字,所以读入停止) ^ 解析得到整数 4193 。 由于 "4193" 在范围 [-231, 231 - 1] 内,最终结果为 4193 。
提示:
0 <= s.length <= 200
s
由英文字母(大写和小写)、数字(0-9)
、' '
、'+'
、'-'
和 '.'
组成
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution {public : int myAtoi (string s) { int k = 0 ; while (k < s.size () && s[k] == ' ' ) k++; int minus = 1 ; if (s[k] == '-' ) minus = -1 , k++; else if (s[k] == '+' ) k++; int res = 0 ; while (k < s.size () && s[k] >= '0' && s[k] <= '9' ){ int x = s[k] - '0' ; if (minus > 0 && res > (INT_MAX - x) / 10 ) return INT_MAX; if (minus < 0 && -res < (INT_MIN + x) / 10 ) return INT_MIN; if (-res * 10 - x == INT_MIN) return INT_MIN; res = res * 10 + x; k++; if (res > INT_MAX) break ; } res *= minus; return res; } };
Let 9:回文数 给你一个整数 x
,如果 x
是一个回文整数,返回 true
;否则,返回 false
。
回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
示例 1:
示例 2:
1 2 3 输入:x = -121 输出:false 解释:从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
示例 3:
1 2 3 输入:x = 10 输出:false 解释:从右向左读, 为 01 。因此它不是一个回文数。
提示:
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution {public : bool isPalindrome (int x) { if (x < 0 ) return false ; int m = x; long long ans = 0 ; while (m){ ans = ans * 10 + m % 10 ; m /= 10 ; } if (ans == x) return true ; return false ; } };
Let 10:正则表达式匹配 * 给你一个字符串 s
和一个字符规律 p
,请你来实现一个支持'.'
和'*'
的正则表达式匹配。
'.'
匹配任意单个字符
'*'
匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个 字符串 s
的,而不是部分字符串。
示例 1:
1 2 3 输入:s = "aa", p = "a" 输出:false 解释:"a" 无法匹配 "aa" 整个字符串。
示例 2:
1 2 3 输入:s = "aa", p = "a*" 输出:true 解释:因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 'a'。因此,字符串 "aa" 可被视为 'a' 重复了一次。
示例 3:
1 2 3 输入:s = "ab", p = ".*" 输出:true 解释:".*" 表示可匹配零个或多个('*')任意字符('.')。
提示:
1 <= s.length <= 20
1 <= p.length <= 30
s
只包含从 a-z
的小写字母。
p
只包含从 a-z
的小写字母,以及字符 .
和*
。
保证每次出现字符*
时,前面都匹配到有效的字符