【Java数据结构】——常见力扣题综合

n数之和

1.两数之和

java 复制代码
    static public int[] twoSum(int[] numbers, int target) {
        int i = 0;
        int j = numbers.length - 1;
        while (i < j) {
            int sum = numbers[i] + numbers[j];
            if (sum < target) {
                i++;
            } else if (sum > target) {
                j--;
            } else {
                break;
            }
        }
        return new int[]{i + 1, j + 1};
    }

2.三数/四数之和

java 复制代码
    public List<List<Integer>> threeSum1(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        Arrays.sort(nums);
        //定义指针
        int l = 0;
        int r = nums.length - 1;
        dfs(nums, result, new LinkedList<>(), 3, l, r, 0);

        return result;
    }

    public void dfs(int[] nums, List<List<Integer>> result, LinkedList<Integer> stack, int n, int l, int r, int target){

        if (n == 2){
            twoSum(nums, result, stack, l , r, target);
            return;
        }

        for (int i = l; i < r - (n - 2); i++) {
            // 检查重复
            if (i > l && nums[i] == nums[i - 1]){
                continue;
            }
            stack.push(nums[i]);
            dfs(nums, result, stack, n - 1, i + 1, r, target - nums[i]);
            stack.pop();
        }
    }

    public List<List<Integer>> twoSum(int[] nums, List<List<Integer>> result, LinkedList<Integer> stack, int l, int r, int target) {
        while(l < r){
            int sum = nums[l] + nums[r];
            if (sum == target){
                List<Integer> list = new ArrayList<>(stack);
                list.add(nums[l]);
                list.add(nums[r]);
                result.add(list);
                //去重
                while(l < r && nums[l] == nums[l + 1]){
                    l++;
                }
                while(l < r && nums[r] == nums[r - 1]){
                    r--;
                }
                l++;
                r--;
            }else if (sum < target){
                l++;
            }else {
                r--;
            }
        }
        return result;
    }

盛水最多的容器(双指针)

java 复制代码
    static int maxArea(int[] height) {
        int i = 0;
        int j = height.length - 1;
        int max = 0;
        while (i < j) {
            if (height[i] < height[j]) {
                int area = (j - i) * height[i];
                max = Math.max(max, area);
                i++;
            } else {
                int area = (j - i) * height[j];
                max = Math.max(max, area);
                j--;
            }
        }
        return max;
    }

滑动窗口最大值(单调队列)

单调队列:要保证值从大到小排列,如果加入队列时前面的元素比后面的大,就要先把比它大的元素先移出来再入队。

构造一个单调递减的队列出来

滑动窗口最大值

java 复制代码
    static int[] maxSlidingWindow(int[] nums, int k) {
        MonotonicQueue queue = new MonotonicQueue();
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < nums.length; i++) {
            // 检查队列头部元素,超过滑动窗口范围要移除
            if (i >= k && queue.peek() == nums[i - k]) {
                queue.poll();
            }
            int num = nums[i];
            queue.offer(num);
            if (i >= (k - 1)) {
//                System.out.println(queue.peek());
                list.add(queue.peek());
            }
        }
        return list.stream().mapToInt(Integer::intValue)
                .toArray();
    }

接雨水(单调栈)

java 复制代码
    static int trap(int[] heights) {
        LinkedList<Data> stack = new LinkedList<>();
        int sum = 0;
        for (int i = 0; i < heights.length; i++) {
            Data right = new Data(heights[i], i);

            while (!stack.isEmpty()
                    && stack.peek().height < right.height) {
                Data pop = stack.pop();
                Data left = stack.peek();
                if (left != null) { // 计算水的容量
                    int width = right.i - left.i - 1;
                    int height = Math.min(left.height, right.height) - pop.height;
                    sum += width * height;
                }
            }

            stack.push(right);
//            System.out.println(stack);
        }
        return sum;
    }

字符串匹配

最长公共前缀

java 复制代码
    static String longestCommonPrefix(String[] strings) {
        /*
            情况1:比较某一列时,遇到不同字符,i 之前的字符就是解
            情况2:比较某一列时,遇到字符串长度不够,i 之前的字符就是解
            情况3:i 循环自然结束,此时第一个字符串就是解
         */
        char[] first = strings[0].toCharArray(); // 第一个字符串
        for (int i = 0; i < first.length; i++) {
            char ch = first[i];
            for (int j = 1; j < strings.length; j++) {
                /*if (strings[j].length() == i) { // 情况 2
                    return new String(first, 0, i);
                }
                if(ch != strings[j].charAt(i)) { // 情况 1
                    return new String(first, 0, i);
                } */
                if (strings[j].length() == i || ch != strings[j].charAt(i)) {
                    return new String(first, 0, i);
                }
            }
        }
        return strings[0];
    }

最长回文子串

java 复制代码
    static String longestPalindrome(String s) {
        left = 0;
        right = 0;
        char[] chars = s.toCharArray();
        for (int i = 0; i < chars.length - 1; i++) {
            extend(chars, i, i); // 一个字符作为中心点
            extend(chars, i, i + 1); // 两个字符作为中心点
        }
        return new String(chars, left, right - left + 1);
    }

    static int left; // i
    static int right; // j

    static void extend(char[] chars, int i, int j) {
        while (i >= 0 && j < chars.length
                && chars[i] == chars[j]) { // 如果是回文,扩大回文范围
            i--; // -1
            j++; // 4
        }
        // 退出循环时,i和j指向的不是回文,需要还原
        i++;
        j--;
        if (j - i > right - left) {
            left = i;
            right = j;
        }
    }

最长覆盖子串

java 复制代码
public class MinWindowLeetcode76_me {

    static class Result {
        int i;
        int j;

        public Result(int i, int j) {
            this.i = i;
            this.j = j;
        }
    }
    static String minWindow(String s, String t) {
        //目标t数组
        char[] target = t.toCharArray();
        //统计目标数组出现次数
        int[] targetCount = new int[128];
        for (char ch : target) {
            targetCount[ch]++;
        }
        print(targetCount);
//---------------目标数组统计-------------------------
        //原数组s
        char[] source = s.toCharArray();
        //统计原数组出现的次数
        int[] sourceCount = new int[128];

//---------------原数组统计-------------------------
        int i = 0;
        int j = 0;
        int passCount = 0;
        for (int count : targetCount){
            if (count > 0){
                passCount++;
            }
        }
        int passed = 0;
        Result res = null;
        while (j < source.length) {
            char right = source[j];
            sourceCount[right]++;
            if (sourceCount[right] == targetCount[right]) {
                passed++;
            }
            while (passed == passCount && i <= j){
                if (res == null) {
                    res = new Result(i, j);
                } else {
                    if (j - i < res.j - res.i) {
                        res = new Result(i, j);
                    }
                }
                char left = source[i];
                sourceCount[left]--;
                if (sourceCount[left] < targetCount[left]) {
                    passed--;
                }
                i++;
            }
            j++;
        }
//        System.out.println(res.i + " " + res.j);
        return res == null ? "" : new String(source, res.i, res.j - res.i + 1);
    }

    static void print(int[] count) {
        System.out.println(IntStream.range(0, count.length)
                .filter(i -> count[i] != 0)
                .boxed()
                .collect(toMap(i -> (char) i.intValue(), i -> count[i])));
    }

    public static void main(String[] args) {
        System.out.println(minWindow("ADOBECODEBANC", "ABC")); // BANC

    }
}

设计短网址

设计推特

股票系列问题

相关推荐
GreatSQL社区3 小时前
GreatSQL 配置 SSL 访问:单机与 MGR 集群指南
1024程序员节
虎冯河4 小时前
图像,视频Lora模型训练的Timestep Type时间步类型
aigc·comfyui·模型训练·1024程序员节
helloworddm4 小时前
Orleans Grain Directory 系统综合分析文档
c#·1024程序员节
I'm Jie4 小时前
(五)Gradle 依赖传递与冲突处理
java·spring boot·spring·kotlin·gradle·maven
我命由我123454 小时前
Spring Cloud - Spring Cloud 声明式接口调用(Fiegn 声明式接口调用概述、Fiegn 使用)
java·后端·spring·spring cloud·微服务·架构·java-ee
_extraordinary_4 小时前
Java Spring事务,事务的传播机制
java·开发语言·spring
摸鱼的老谭4 小时前
Java学习之旅第三季-17:Lambda表达式
java·lambda表达式·1024程序员节
冰山上的柯莱4 小时前
需求上线部署流程
1024程序员节·上线流程
文火冰糖的硅基工坊4 小时前
[人工智能-大模型-66]:模型层技术 - 两种编程范式:数学函数式编程与逻辑推理式编程,构建起截然不同的智能系统。
人工智能·神经网络·算法·1024程序员节