LeetCode寒假刷题 Day04


前言

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我鸭!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值