LeetCode -- Flora -- edit 2025-04-27

1.接雨水

42. 接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

示例 1:

复制代码
输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 

示例 2:

复制代码
输入:height = [4,2,0,3,2,5]
输出:9

提示:

  • n == height.length
  • 1 <= n <= 2 * 104
  • 0 <= height[i] <= 105
java 复制代码
    public static void main(String[] args) {
        int[] nums = {0,1,0,2,1,0,1,3,2,1,2,1};
        int trap = trap2(nums);
        System.out.println(trap);
    }

    /**
     * others:
     * 思路:
     * 使用双指针,左、右往中间逼近,找碗(的条件:左高中低右高,右≥左>中)
     * eg.int[] nums = {0,2,1,3,1,2,1};
     * 左<右,左指针动
     * 左≥右,右指针动(碗的条件:左高中低右高,右≥左>中)
     * ①从左往右看,成碗(0<1),左动,格子没下降(没办法装水),s不变,s=0
     * ②从右往左看,成碗(2>1),右动,格子没下降(没办法装水),s不变,s=0
     * ③从右往左看,成碗(2<=2),右动,格子下降,s=0+下降的高度=1
     * ④从左往右看,成碗(2>1),左动,格子下降,s=1+下降的高度=2
     * ⑤从右往左看,成碗(1<=1),右动,格子没下降(没办法装水),s不变,s=2
     * ⑥从右往左看,成碗(1<=3),右动,左右指针相遇,结束
     * max值的作用,判断格子是否下降(与指针所在值比较)
     * @param height
     * @return
     */
    public static int trap2(int[] height) {
        int ans = 0;
        int left = 0, right = height.length - 1;
        int leftMax = 0, rightMax = 0;
        while (left < right) {
            leftMax = Math.max(leftMax, height[left]);
            rightMax = Math.max(rightMax, height[right]);
            if (height[left] < height[right]) {
                ans += leftMax - height[left];
                ++left;
            } else {
                ans += rightMax - height[right];
                --right;
            }
        }
        return ans;
    }

    /**
     * my:
     * 思路:
     * 单向遍历判断,存储成碗的区间index,尾巴处(最后一个区间index)可能存在不满足成碗(右≥左>中)的特殊情况,左>右,逆序后调用一次方法本身可解决
     * @param height
     * @return
     */
    public static int trap(int[] height) {
        List<List<Integer>> indexList = new ArrayList<>();
        for (int i = 0; i+1 < height.length; i++) {
            if (height[i]>height[i+1]){
                List<Integer> inner = new ArrayList<>();
                inner.add(i);
                for (int j = i + 1; j < height.length; j++) {
                    inner.add(j);
                    if (height[j] >= height[i])
                        break;
                }
                indexList.add(inner);
                int jumpIndex = inner.size();
                if (jumpIndex > 0)
                    i = i + jumpIndex - 2;
            }
        }
        List<Integer> targetList = new ArrayList<>();
        for (List<Integer> innerIndexList : indexList) {
            if (height[innerIndexList.get(0)]>height[innerIndexList.get(innerIndexList.size()-1)]){
                // 创建新数组
                int[] reversedArray = new int[innerIndexList.size()];
                // 逆序填充
                for (int i = 0; i < innerIndexList.size(); i++) {
                    reversedArray[i] = height[innerIndexList.get(innerIndexList.size() - 1 - i)]; // 从后往前取
                }

                int trap = trap(reversedArray);
                targetList.add(trap);
            }else {
                int innerHeight = height[innerIndexList.get(0)];
                // 使用 IntStream.sum()(更高效)
                int sum = innerIndexList
                        .stream()
                        .mapToInt(o -> innerHeight >= height[o] ? innerHeight - height[o] : 0)
                        .sum();
                targetList.add(sum);
            }
        }
        // 使用 IntStream.sum()(更高效)
        int sum = targetList
                .stream()
                .mapToInt(Integer::intValue).sum();
        return sum;
    }

思路不一样

2.无重复字符的最长子串

3. 无重复字符的最长子串

给定一个字符串 s ,请你找出其中不含有重复字符的 最长 子串 的长度。

示例 1:

复制代码
输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:

复制代码
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:

复制代码
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

提示:

  • 0 <= s.length <= 5 * 104
  • s 由英文字母、数字、符号和空格组成
java 复制代码
    public static void main(String[] args) {
        String s1 = "pwwkew";
        String s2 = " ";
        String s = "dvdf";
        int lengthOfLongestSubstring = lengthOfLongestSubstring(s);
        System.out.println(lengthOfLongestSubstring);
    }

    /**
     * 思路:
     * 滑动窗口
     *
     * 关键步骤:
     * 1.右指针 right 扩展窗口:
     * 遍历每个字符,尝试将其加入当前窗口。
     * 2.处理重复字符:
     * 如果 c[right] 已经在窗口中(cnt[c[right]] > 0),则移动左指针 left,并减少对应字符的计数,直到 c[right] 不再重复。
     * 3.更新窗口长度:
     * 计算当前窗口长度 right - left + 1,并更新最大值 ans。
     * @param s
     * @return
     */
    public static int lengthOfLongestSubstring2(String s) {
        int ans = 0;          // 存储最长无重复子串的长度
        int left = 0;         // 滑动窗口的左边界
        char[] c = s.toCharArray();  // 将字符串转为字符数组,方便遍历
        int n = c.length;     // 字符串长度
        int[] cnt = new int[128];  // ASCII 字符计数数组(默认初始化为 0)

        //cnt[128]:用于记录当前窗口中每个字符的出现次数(ASCII 字符范围 0-127)。
        //left 和 right:定义滑动窗口的左右边界。

        for (int right = 0; right < n; right++) {
            // 如果当前字符 c[right] 已经存在于窗口中,则移动左边界
            while (cnt[c[right]] > 0) {
                cnt[c[left]]--;  // 移除左边界字符的计数
                left++;          // 左边界右移
            }
            // 将当前字符加入窗口
            cnt[c[right]]++;
            // 更新最大长度
            ans = Math.max(ans, right - left + 1);
        }
        return ans;
    }

    public static int lengthOfLongestSubstring(String s) {
        String currentSubstring = "";
        int longestLen = 0;

        for (int i = 0; i < s.length(); i++) {
            if (currentSubstring.contains(String.valueOf(s.charAt(i)))) {
                if (currentSubstring.length()>longestLen){
                    longestLen = currentSubstring.length();
                }
                int indexOf = currentSubstring.indexOf(s.charAt(i));
                if (indexOf+1 <= s.length()-1){
                    currentSubstring = currentSubstring.substring(indexOf + 1);
                }else {
                    currentSubstring = "";
                }
            }
            currentSubstring+=s.charAt(i);
        }
        if (currentSubstring.length()>longestLen){
            longestLen = currentSubstring.length();
        }
        return longestLen;
    }

思路一样

相关推荐
PXM的算法星球1 小时前
【leetcode】3524 求出数组的X值1
算法·leetcode·职场和发展
缘友一世4 小时前
从线性回归到逻辑回归
算法·逻辑回归·线性回归
前端_学习之路5 小时前
javaScript--数据结构和算法
javascript·数据结构·算法
迷路的小绅士5 小时前
计算机网络核心知识点全解析(面试通关版)
计算机网络·面试·职场和发展
weixin_428498495 小时前
使用HYPRE库并行装配IJ稀疏矩阵指南: 矩阵预分配和重复利用
算法·矩阵
雾削木7 小时前
mAh 与 Wh:电量单位的深度解析
开发语言·c++·单片机·嵌入式硬件·算法·电脑
__lost7 小时前
小球在摆线上下落的物理过程MATLAB代码
开发语言·算法·matlab
中小企业实战军师刘孙亮8 小时前
实体店的小程序转型之路:拥抱新零售的密码-中小企实战运营和营销工作室博客
职场和发展·小程序·创业创新·学习方法·业界资讯·零售·内容运营
mit6.8249 小时前
[Lc_week] 447 | 155 | Q1 | hash | pair {}调用
算法·leetcode·哈希算法·散列表