文章目录
前言
LeetCode第4天,今天主要用到的是双指针知识以及一些简单的栈和链表的操作。
一、016 最接近的三数之和
1. 题目描述
题号:16
难度:中等
最接近的三数之和
给定一个包括n个整数的数组nums和一个目标值target。找出nums中的三个整数,使得它们的和与target最接近。返回这三个数的和。假定每组输入只存在唯一答案。
示例 :
例如,给定数组 nums = [-1,2,1,-4], 和 target = 1. 与 target 最接近的三个数的和为 2.
(-1 +2 + 1 = 2).
2. 解题思路
与昨天的 015 三数之和 类似,采用双指针的思想,避免了暴力的三重循环。
3. 代码实现
class Solution {
public int threeSumClosest(int[] nums, int target) {
Arrays.sort(nums);
if(nums.length==3)
return nums[0]+nums[1]+nums[2];
int i=0,j=1,k=2;
int value=Integer.MAX_VALUE;
int pre=value;
int val=Integer.MAX_VALUE;
int flag=1;
while(i< nums.length-1)
{
while(i>=0&&k< nums.length&&val!=0)
{
value=nums[i]+nums[j]+nums[k]-target;
val=Math.min(val,Math.abs(value));
if(val==-value)
flag=-1;
else if(val==value)
flag=1;
pre=value;
if(value>0) {
if(i==0)
--i;
while (i > 0 && nums[--i] == nums[i + 1]);
}
else
{
if(k==nums.length-1)
++k;
while(k< nums.length-1&&nums[++k]==nums[k-1]);
}
continue;
}
if(val==0)
{
return target;
}
++j;
i=j-1;
k=j+1;
}
return target+flag*val;
}
}
二、020 有效的括号
1. 题目描述
题号:20
难度:简单
有效的括号
给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。
示例 1:
输入: “()”
输出: true
示例 2:
输入: “()[]{}”
输出: true
示例 3:
输入: “(]”
输出: false
示例 4:
输入: “([)]”
输出: false
示例 5:
输入: “{[]}”
输出: true
示例 6:
输入: “”
输出: true
示例 7:
输入: “((”
输出: false
2. 解题思路
这个不用多说了,就是简单的括号匹配,一般而言,关于表达式求值、括号匹配等问题,都是通过栈来实现。
就这道问题而言,我们可以首先将表达式中的前缀括号“( [ { ”入栈,若遇到的不是这三个,则为后缀括号,将出栈并与之匹配;若两者不匹配,返回false。若此时栈中没有元素,返回false。若最终表达式遍历完后,栈仍然不为空,返回false。其余情况,最终的返回值为true。
3. 代码实现
class Solution {
public boolean isValid(String s) {
if(s.length()%2==1)
return false;
int i=0,j=s.length()-1;
Map<Character,Character> map =new HashMap<Character,Character>();
map.put('[',']');
map.put('{','}');
map.put('(',')');
Stack <Character>stack=new <Character>Stack();
for(i=0;i<s.length();i++)
{
if(map.containsKey(s.charAt(i)))
stack.push(s.charAt(i));
else
{
if(stack.empty())
return false;
if(map.get(stack.pop())!=s.charAt(i))
return false;
}
}
if(!stack.empty())
return false;
return true;
}
}
三、021 合并两个有序链表
1. 题目描述
题号:21
难度:简单
合并两个有序链表
将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
2. 解题思路
借助了归并排序中的将两个有序数组合并为一个的思想。为了不new新的节点占用空间,我们将l1链表作为基准链表,将l2插入l1的适当位置。
3. 代码实现
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if(l1==null)
return l2;
ListNode head1=new ListNode(0,l1);
l1=head1;
ListNode head2=new ListNode(0,l2);
ListNode now=l2;
while(head1.next!=null&&head2.next!=null)
{
if(head2.next.val<head1.next.val)
{
now=head2.next;
head2.next=now.next;
now.next=head1.next;
head1.next=now;
head1=now;
}
else
{
head1=head1.next;
}
}
while(head2.next!=null)
{
now=head2.next;
head2.next=now.next;
now.next=head1.next;
head1.next=now;
head1=now;
}
l1=l1.next;
return l1;
}
}
总结
以上就是今天LeetCode寒假刷题的第四天所做的三道题。若有任何疑问,欢迎私信Call我鸭!