Day1:LeetCode_18&&LeetCode_20

从今天开始我就要正式回归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%了,有点意思?)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值