算法刷题打卡(四)

15 三数之和

15. 三数之和 - 力扣(LeetCode) (leetcode-cn.com)

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
示例 2:

输入:nums = []
输出:[]
示例 3:

输入:nums = [0]
输出:[]

是 a+b+c = 0

数组排序, 一个指针 从左往右走 当前位置的数 i ,i位置得数当作三元组得第一个数,在 后边 找 和在 (0-nums[i]) 得一个二元组

​ 当 i 来到下一个位置得时候 发现跟前面得数一样直接跳过

例: -5,-5,-5,-1,0,1,5… 当来到第一个 -5 得时候 在来到第二个-5可以直接跳过,因为在第一个-5得时候 就把 以-5 第一个数得,所有得二元组都求过了

不需要在以 第二个 -5 去求

 	public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> ans = new ArrayList<>();
        for (int i = 0; i < nums.length - 2; i++) {
            if (i == 0 || nums[i - 1] != nums[i]) {
                List<List<Integer>> two = twoSum(nums, i + 1, -nums[i]);
                for (List<Integer> cur : two) {
                    cur.add(0, nums[i]);
                    ans.add(cur);
                }
            }
            if (nums[i] > 0){ //因为数组是排好序的 i后边的数 都是 大于它的
                return ans;
            }
        }
        return ans;
    }

    // nums已经有序了
    public static List<List<Integer>> twoSum(int[] nums, int start, int target) {
        int L = start;
        int R = nums.length - 1;
        List<List<Integer>> ans = new ArrayList<>();
        while (L < R) {
            if (nums[L] + nums[R] > target) {
                R--;
            } else if (nums[L] + nums[R] < target) {
                L++;
            } else {//相等,  保证你左边的数和当前的数 不相等
                if (L == start || nums[L - 1] != nums[L]) {
                    List<Integer> cur = new ArrayList<>();
                    cur.add(nums[L]);
                    cur.add(nums[R]);
                    ans.add(cur);
                }
                L++;
            }
        }
        return ans;
    }

17 电话号码的字母组合

17. 电话号码的字母组合 - 力扣(LeetCode) (leetcode-cn.com)

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

在这里插入图片描述

示例 1:

输入:digits = “23”
输出:[“ad”,“ae”,“af”,“bd”,“be”,“bf”,“cd”,“ce”,“cf”]
示例 2:

输入:digits = “”
输出:[]
示例 3:

输入:digits = “2”
输出:[“a”,“b”,“c”]

每条路线都走一下

     static char[][] p = {
            {'a', 'b', 'c'},      // 2    0
            {'d', 'e', 'f'},      // 3    1
            {'g', 'h', 'i'},      // 4    2
            {'j', 'k', 'l'},      // 5    3
            {'m', 'n', 'o'},      // 6    4
            {'p', 'q', 'r', 's'}, // 7    5
            {'t', 'u', 'v'},      // 8    6
            {'w', 'x', 'y', 'z'}, // 9    7
    };

    public List<String> letterCombinations(String digits) {
        List<String> ans = new ArrayList<>();
        if (digits == null || digits.length() == 0) {
            return ans;
        }
        char[] str = digits.toCharArray();
        char[] path = new char[str.length];//path 之前按出的结果
        process(str, 0, path, ans);
        return ans;
    }

    public static void process(char[] str, int index, char[] path, List<String> ans) {
        if (index == str.length) {
            ans.add(String.valueOf(path));
        } else {
            char[] chars = p[str[index] - '2'];
            for (char cur : chars) {
                path[index] = cur; //当前字符 的每种路线都走一下
                process(str,index+1,path,ans);
            }
        }
    }

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

19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode) (leetcode-cn.com)

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

进阶你能尝试使用一趟扫描实现吗?

在这里插入图片描述

输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
示例 2:

输入:head = [1], n = 1
输出:[]
示例 3:

输入:head = [1,2], n = 1
输出:[1]

双指针,先数出来 n个 然后 双指针,一起移动 到达尾部的时候,另外一个就是倒数第N个节点 ,但是删掉节点 是要找到他的前一个节点,指向它的下一个

就是 要删除节点的前一个。

    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode cur = head;
        ListNode pre = null;
        boolean flag = false;
        while (cur != null) {//结束 之后 pre就是 要删除的 前一个
            n--;
            if (n <= 0) {
                if (n == 0) {
                    flag = true; //已经 n 个数了
                } else if (n == -1) {//此时标记 pre
                    pre = head;
                } else {
                    pre = pre.next;
                }
            }
            cur = cur.next;
        }
        if (!flag) {//够不够
            return head;
        }
        if (pre == null) {//说明要删除的是 头节点
            return head.next;
        }
        pre.next = pre.next.next;
        return head;
    }

20 有效的括号

20. 有效的括号 - 力扣(LeetCode) (leetcode-cn.com)

给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。

示例 1:

输入:s = “()”
输出:true
示例 2:

输入:s = “()[]{}”
输出:true
示例 3:

输入:s = “(]”
输出:false
示例 4:

输入:s = “([)]”
输出:false
示例 5:

输入:s = “{[]}”
输出:true

栈,遇到左括号 入栈,右括号弹,匹配上继续,匹配不上 拜拜,最后栈为空。

    public boolean isValid(String s) {
      if (s == null || s.length() == 0) {
            return true;
        }
        char[] str = s.toCharArray();
        Stack<Character> stack = new Stack<>();
        for (int i = 0; i < str.length; i++) {
            char c = str[i];
            if (c == '(' || c == '[' || c == '{') {
                stack.add(c == '(' ? ')' : (c == '[' ? ']' : '}'));
            } else {
                if (stack.isEmpty()) {
                    return false;
                }
                char last = stack.pop();
                if (c != last) {
                    return false;
                }
            }
        }
        return stack.isEmpty();
    }
  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值