11. 盛最多水的容器
难度中等1811
给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器,且 n 的值至少为 2。
图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
示例:
输入:[1,8,6,2,5,4,8,3,7]
输出:49
双指针法,缩减搜索空间的思想去考虑题解,做出来之后还是有可能做不出来。
用一句话概括双指针解法的要点:指针每一次移动,都意味着排除掉了一个柱子。
(看动图!)
作者:nettee
链接:https://leetcode-cn.com/problems/container-with-most-water/solution/on-shuang-zhi-zhen-jie-fa-li-jie-zheng-que-xing-tu/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
public:
int maxArea(vector& height) {
int x=0,y=height.size()-1;
int ans=0;
while(x!=y){
int tmp=min(height[x],height[y])*(y-x);
if(tmp>ans) ans=tmp;
if(min(height[x],height[y])==height[x]){
x++;
}else y--;
}
return ans;
}
};
12. 整数转罗马数字
难度中等404
罗马数字包含以下七种字符: I
, V
, X
, L
,C
,D
和 M
。
字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000
例如, 罗马数字 2 写做 II
,即为两个并列的 1。12 写做 XII
,即为 X
+ II
。 27 写做 XXVII
, 即为 XX
+ V
+ II
。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII
,而是 IV
。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX
。这个特殊的规则只适用于以下六种情况:
I
可以放在 V
(5) 和 X
(10) 的左边,来表示 4 和 9。X
可以放在 L
(50) 和 C
(100) 的左边,来表示 40 和 90。 C
可以放在 D
(500) 和 M
(1000) 的左边,来表示 400 和 900。给定一个整数,将其转为罗马数字。输入确保在 1 到 3999 的范围内。
示例 1:
输入: 3 输出: "III"
示例 2:
输入: 4 输出: "IV"
示例 3:
输入: 9 输出: "IX"
示例 4:
输入: 58 输出: "LVIII" 解释: L = 50, V = 5, III = 3.
示例 5:
输入: 1994 输出: "MCMXCIV" 解释: M = 1000, CM = 900, XC = 90, IV = 4.
好像就是非常普通的贪心hhh
class Solution {
public:
unordered_map mp={
{1,"I"},{5,"V"},{10,"X"},{50,"L"},{100,"C"},{500,"D"},{1000,"M"},
{4,"IV"},{9,"IX"},{40,"XL"},{90,"XC"},{400,"CD"},{900,"CM"}};
vector d={1000,900,500,400,100,90,50,40,10,9,5,4,1};
string intToRoman(int num) {
if(num==0) return "";
for(int i=0;i=d[i]){
return mp[d[i]]+intToRoman(num-d[i]);break;
}
}
return "";//
}
};
13. 罗马数字转整数
难度简单1028
罗马数字包含以下七种字符: I
, V
, X
, L
,C
,D
和 M
。
字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000
例如, 罗马数字 2 写做 II
,即为两个并列的 1。12 写做 XII
,即为 X
+ II
。 27 写做 XXVII
, 即为 XX
+ V
+ II
。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII
,而是 IV
。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX
。这个特殊的规则只适用于以下六种情况:
I
可以放在 V
(5) 和 X
(10) 的左边,来表示 4 和 9。X
可以放在 L
(50) 和 C
(100) 的左边,来表示 40 和 90。 C
可以放在 D
(500) 和 M
(1000) 的左边,来表示 400 和 900。给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。
示例 1:
输入: "III" 输出: 3
示例 2:
输入: "IV" 输出: 4
示例 3:
输入: "IX" 输出: 9
示例 4:
输入: "LVIII" 输出: 58 解释: L = 50, V= 5, III = 3.
示例 5:
输入: "MCMXCIV" 输出: 1994 解释: M = 1000, CM = 900, XC = 90, IV = 4.
提示:
啊......反正方法好像都差不多,但是执行效率差很多...?
class Solution {
public int romanToInt(String s) {
int sum = 0;
int preNum = getValue(s.charAt(0));
for(int i = 1;i < s.length(); i ++) {
int num = getValue(s.charAt(i));
if(preNum < num) {
sum -= preNum;
} else {
sum += preNum;
}
preNum = num;
}
sum += preNum;
return sum;
}
private int getValue(char ch) {
switch(ch) {
case 'I': return 1;
case 'V': return 5;
case 'X': return 10;
case 'L': return 50;
case 'C': return 100;
case 'D': return 500;
case 'M': return 1000;
default: return 0;
}
}
}
作者:donespeak
链接:https://leetcode-cn.com/problems/roman-to-integer/solution/yong-shi-9993nei-cun-9873jian-dan-jie-fa-by-donesp/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
14. 最长公共前缀
难度简单1254
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""
。
示例 1:
输入: ["flower","flow","flight"] 输出: "fl"
示例 2:
输入: ["dog","racecar","car"] 输出: "" 解释: 输入不存在公共前缀。
说明:
所有输入只包含小写字母 a-z
。
这个效率还可以诶??
class Solution {
public:
string longestCommonPrefix(vector& strs) {
string ans="";
int n=strs.size();
if(n==0) return "";
unordered_map mp;
int index=0;
while(1){
for(int i=0;i
15. 三数之和
难度中等2564
给你一个包含 n 个整数的数组 nums
,判断 nums
中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例:
给定数组 nums = [-1, 0, 1, 2, -1, -4], 满足要求的三元组集合为: [ [-1, 0, 1], [-1, -1, 2] ]
class Solution {
public:
vector> twoSum(vector nums,int target,int start){
int l=start;int r=nums.size()-1;
vector> ans;
while(ltarget){
r--;
while(l> threeSum(vector& nums) {
vector> ans;
sort(nums.begin(),nums.end());
for(int i=0;i> tuples=twoSum(nums,0-nums[i],i+1);
for(vector& tuple:tuples){
tuple.push_back(nums[i]);
ans.push_back(tuple);
}
while(i
16. 最接近的三数之和
难度中等565
给定一个包括 n 个整数的数组 nums
和 一个目标值 target
。找出 nums
中的三个整数,使得它们的和与 target
最接近。返回这三个数的和。假定每组输入只存在唯一答案。
示例:
输入:nums = [-1,2,1,-4], target = 1 输出:2 解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。
class Solution {
public:
//最接近的两数之和??
int twoSum(vector& nums,int target,int start){
int l=start;int r=nums.size()-1;
int ans;int difference=10e8;
while(ltarget){
r--;while(l& nums, int target) {
//-4 -1 1 2
//所有不重复的...
int ans;
int difference=10e8;
sort(nums.begin(),nums.end());
for(int i=0;i
class Solution {
public int threeSumClosest(int[] nums, int target) {
Arrays.sort(nums);
int ans = nums[0] + nums[1] + nums[2];
for(int i=0;i target)
end--;
else if(sum < target)
start++;
else
return ans;
}
}
return ans;
}
}
17. 电话号码的字母组合
难度中等909
给定一个仅包含数字 2-9
的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例:
输入:"23" 输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
说明:
尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。
平平无奇的dfs
class Solution {
public:
vector letterCombinations(string digits) {
if (digits.length() == 0) return res;
backTrace(digits, 0);
return res;
}
private:
unordered_map phoneString {
{'2',"abc"},
{'3',"def"},
{'4',"ghi"},
{'5',"jkl"},
{'6',"mno"},
{'7',"pqrs"},
{'8',"tuv"},
{'9',"wxyz"},
};
string s;
vector res;
void backTrace(string digits, int index)
{
if(digits.size() == index) {
res.push_back(s);
}
for (int i = 0; i < phoneString[digits[index]].size(); ++i) {
s += phoneString[digits[index]][i];
backTrace(digits, index+1);
s.pop_back();
}
}
};
18. 四数之和
难度中等564
给定一个包含 n 个整数的数组 nums
和一个目标值 target
,判断 nums
中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target
相等?找出所有满足条件且不重复的四元组。
注意:
答案中不可以包含重复的四元组。
示例:
给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。 满足要求的四元组集合为: [ [-1, 0, 0, 1], [-2, -1, 1, 2], [-2, 0, 0, 2] ]
class Solution {
public:
vector> fourSum(vector& nums, int target) {
sort(nums.begin(),nums.end());
vector > res;
for(int i = 0; i + 3 < nums.size(); ++i)
{
if(i > 0 && nums[i] == nums[i-1]) continue;
for(int j = i+1; j + 2 < nums.size(); ++j)
{
if(j > i+1 && nums[j] == nums[j-1]) continue;
//此处不能为j>0,循环至少进行一轮后才能continue,确保当前情况的数字组合已经判断过
int ttarget = target - nums[i] - nums[j] ;
int l = j+1, r = nums.size()-1;
while(l < r)
{
int sum = nums[l] + nums[r]; //注意-号
if(ttarget == sum)
{
res.push_back({nums[i],nums[j],nums[l],nums[r]});
l++;
r--;
while(l < r && nums[l] == nums[l-1]) l++;
while(l < r && nums[r] == nums[r+1]) r--;
}
if(ttarget > sum) l++;
if(ttarget < sum) r--;
}
}
}
return res;
}
};
作者:zrita
链接:https://leetcode-cn.com/problems/4sum/solution/c-z-by-zrita-17/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
19. 删除链表的倒数第N个节点
难度中等983
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:
给定的 n 保证是有效的。
进阶:
你能尝试使用一趟扫描实现吗?
//一次遍历的答案就是
快慢指针~!
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* ans=new ListNode(0);
ans->next=head;
ListNode* first=ans;
ListNode* second=ans;
for(int i=0;i<=n;i++){
first=first->next;
}
//second->0->1... first->2
while(first!=NULL){
first=first->next;
second=second->next;
}
second->next=second->next->next;
return ans->next;
}
};
20. 有效的括号
难度简单1846
给定一个只包括 '('
,')'
,'{'
,'}'
,'['
,']'
的字符串,判断字符串是否有效。
有效字符串需满足:
注意空字符串可被认为是有效字符串。
示例 1:
输入: "()" 输出: true
示例 2:
输入: "()[]{}" 输出: true
示例 3:
输入: "(]" 输出: false
示例 4:
输入: "([)]" 输出: false
示例 5:
输入: "{[]}" 输出: true
class Solution {
public:
bool isValid(string s) {
stack st;
if(s.length()==0) return true;
st.push(s[0]);
for(int i=1;i