从今天开始我就要正式回归LeetCode,暑假还是不要荒废为好。废话不多说,上题吧!
-
LeetCode_18(难度:中等)(点击此处跳转题目):
给定一个包含 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]
]
思路:
和大多数人第一感觉一样,我首先想到的是四层循环的暴力遍历法(回溯递归也行,剪枝函数也比较好写),就四个指针变量依次从左往右遍历,当找到和为target的位置时就记录下来(我没有在此时进行数组去重,我放在了另一个叫wash()的函数中),该方法的时间复杂度初步估计时O(n4),毫无疑问超时了,所以需要对此方法进行改进。
FourSum与ThreeSum和TwoSum可以归为一类题,即使用双指针来减少循环层数从而降低时间复杂度,而双指针大概可以降低O(n2)级的时间复杂度,所以上面方法的时间复杂度降为O(n2)(不是很严谨,如有错误希望能指出,谢谢)
双指针代码如下:
//这是主要功能函数
vector<vector<int>>fun2(vector<int>& nums, int target)
{
if (nums.size()<=3)
{
return {};
}
sort(nums.begin(),nums.end());
vector<vector<int>>ans;
for (int i = 0; i < nums.size(); i++)
{
if (i > 0 && nums[i] == nums[i - 1])continue;
for (int j = i+1; j < nums.size(); j++)
{
if (j > i + 1 && nums[j] == nums[j - 1])continue;
int left = j + 1, right = nums.size() - 1;
while (left<right)
{
int sum = nums[i] + nums[j] + nums[left] + nums[right];
if (sum>target)
{
right--;
}
else if (sum<target)
{
left++;
}
else
{
ans.push_back(vector<int>{nums[i],nums[j],nums[left],nums[right]});
left++;
right--;
}
}
}
}
wash(ans);
return ans;
};
//本函数用于对vector数组去重
void wash(vector<vector<int>>& ans)
{
vector<vector<int>>new_ans;
for (auto var:ans)
{
sort(var.begin(), var.end());
if (new_ans.empty())
{
new_ans.push_back(var);
}
else
{
bool flag = false;
for (auto vec:new_ans )
{
if (vec==var)
{
flag = true;
break;
}
}
if (!flag)
{
new_ans.push_back(var);
}
}
}
ans = new_ans;
}
-
LeetCode_20(难度:简单)(点击此处跳转题目)
给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。示例 1:
输入: “()”
输出: true
示例 2:输入: “()[]{}”
输出: true
示例 3:输入: “(]”
输出: false
示例 4:输入: “([)]”
输出: false
示例 5:输入: “{[]}”
输出: true
思路:
本题比较简单且解法较多,容易想到的解法是用stack来做,将一个一个字符压入栈内,当字符属于左半边(即‘(’、’[’、’{’)时直接压入栈,当碰到字符属于右半边时取出栈顶字符看两者是否匹配,如果匹配则将栈顶元素弹出,进行下一次比较,如果碰见一次不匹配的情况直接返回false,而但所有字符判断完后还没有碰见不匹配的情况就
return true&&stack.empty()
之所以要加上stack.empty()原因是防止输入的字符为一个的情况(当然你也可以在函数最前面判断一下)
bool isValid(string s)
{
stack <char>st;
for (unsigned int i = 0 ; i <s.length() ; i++)
{
char var = s[i];
if (st.empty() || var == '(' || var == '[' || var == '{')
{
st.push(var);
}
else
{
char top = st.top();
if (top=='('&&var!=')'||top=='{'&&var!='}'||top=='['&&var!=']')
{
return false;
}
else
{
st.pop();
continue;
}
}
}
return true&&st.empty();
}
(额,不知道怎么就时间超过100%了,有点意思?)