LeetCode 16~20

前言

本文隶属于专栏《LeetCode 刷题汇总》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢!

本专栏目录结构请见LeetCode 刷题汇总

正文

幕布

在这里插入图片描述

幕布链接

16. 最接近的三数之和

题解

画解算法:16. 最接近的三数之和

sort+双指针+abs

class Solution {

    public int threeSumClosest(int[] nums, int target) {
        int len = nums.length, result = nums[0] + nums[1] + nums[len - 1];
        Arrays.sort(nums);
        for (int i = 0; i < len - 2; i++) {
            int start = i + 1, end = len - 1;
            while (start < end) {
                int sum = nums[i] + nums[start] + nums[end];
                if (sum > target) {
                    end--;
                } else {
                    start++;
                }
                if (Math.abs(sum - target) < Math.abs(result - target)) {
                    result = sum;
                }
            }
        }
        return result;
    }
}

17. 电话号码的字母组合

题解

My java solution with FIFO queue

回溯+sb

class Solution {
    String[] letters = {"*","#","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
    public List<String> letterCombinations(String digits) {
        List<String> res = new ArrayList<>();
        if (digits == null || digits.length() == 0) return res;
        StringBuilder path = new StringBuilder(digits.length());
        backtracking(path, res, digits, 0);
        return res;
    }
    private void backtracking(StringBuilder path, List<String> res, String digits, int index) {
        if (index == digits.length()){
            res.add(path.toString());
            return;
        }
        char c = digits.charAt(index);
        int pos = c - '0';
        String map_string = letters[pos];
        for (int i = 0; i < map_string.length(); i++){
            path.append(map_string.charAt(i));
            backtracking(path, res, digits, index+1);
            path.deleteCharAt(path.length() - 1);
        }
    }
}

数组+队列

class Solution {
  public List<String> letterCombinations(String digits) {
		LinkedList<String> ans = new LinkedList<String>();
		if(digits.isEmpty()) return ans;
		String[] mapping = new String[] {"0", "1", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
		ans.add("");
		while(ans.peek().length() != digits.length()){
			String remove = ans.remove();
			String map = mapping[digits.charAt(remove.length()) - '0'];
			for(char c: map.toCharArray()){
				ans.addLast(remove + c);
			}
		}
		return ans;
	}
}

18. 四数之和

题解

官方题解

sort+continue/break/continue+双指针

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> res = new ArrayList<>();
        int n = nums.length;
        if(n < 4){
            return res;
        }
        Arrays.sort(nums);
        for(int i = 0; i < n - 3; i++){
            if(i > 0 && nums[i] == nums[i - 1]){
                continue;
            }
            if(nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target){
                break;
            }
            if(nums[i] + nums[n - 1] + nums[n - 2] + nums[n - 3] < target){
                continue;
            }
            int threeSum = target - nums[i];
            for(int j = i + 1; j < n - 2; j++){
                if(j > i + 1 && nums[j] == nums[j - 1]){
                    continue;
                }
                if(nums[j] + nums[j + 1] + nums[j + 2] > threeSum){
                    break;
                }
                if(nums[j] + nums[n - 1] + nums[n - 2] < threeSum){
                    continue;
                }
                int twoSum = threeSum - nums[j];
                int three = j + 1, four = n - 1;
                while(three < four){
                    int sum = nums[three] + nums[four];
                    if(sum == twoSum){
                        res.add(Arrays.asList(nums[i], nums[j], nums[three], nums[four]));
                    }
                    if(sum < twoSum){
                        three++;
                        while(three < four && nums[three] == nums[three - 1]) three++;
                    }else{
                        four--;
                        while(three < four && nums[four] == nums[four + 1]) four--;
                    }
                }
            }
        }
        return res;
    }
}

19. 删除链表的倒数第 N 个结点

题解

动画图解 LeetCode 第 19 号问题:删除链表的倒数第 N 个节点

双指针

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode slow = head, fast = head;
        for(int i = 0; i < n; i++){
            fast = fast.next;
        }
        if(fast == null){
            return head.next;
        }
        while(fast.next != null){
            slow = slow.next;
            fast = fast.next;
        }
        slow.next = slow.next.next;
        return head;
    }
}

20. 有效的括号

题解

逐步分析,图解栈(栈是最标准的解法,大家不要争了)

class Solution {
    public boolean isValid(String s) {
        ArrayDeque<Character> stack = new ArrayDeque<>();
        for(char c : s.toCharArray()){
            if(c == '('){
                stack.push(')');
            }else if(c == '['){
                stack.push(']');
            }else if(c == '{'){
                stack.push('}');
            }else if(stack.isEmpty() || c != stack.peek()){
                return false;
            }else{
                stack.pop();
            }
        }
        return stack.isEmpty();
    }
}
  • 12
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值