测试

经典例题

package org.example.algorithm.array;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * 数组与双指针 — 经典题
 * <p>
 * 1. 两数之和 II(有序) LeetCode 167
 * 2. 盛最多水的容器     LeetCode 11
 * 3. 无重复字符的最长子串 LeetCode 3
 */
public class ArrayProblems {

    /**
     * 题意:有序数组中找两数之和 = target,返回 1-based 下标。
     * 思路:对撞指针,sum 小则 L++,大则 R--。
     * 复杂度:O(n) 时间,O(1) 空间。
     * 易错:下标从 1 开始;不要用 HashMap 忘了「有序」条件。
     */
    public int[] twoSum(int[] numbers, int target) {
        int L = 0, R = numbers.length - 1;
        while (L < R) {
            int sum = numbers[L] + numbers[R];
            if (sum == target) {
                return new int[]{L + 1, R + 1};
            } else if (sum < target) {
                L++;
            } else {
                R--;
            }
        }
        return new int[]{-1, -1};
    }

    /**
     * 题意:两条竖线与 x 轴构成容器,求最大盛水量。
     * 思路:对撞;面积 = min(h[L],h[R]) * (R-L)。
     *       移动较矮的一边(高的不动,宽变小只会更差或不变)。
     * 复杂度:O(n) / O(1)
     * 易错:先算面积再移动;两边等高时可任意移一边或两边都移。
     */
    public int maxArea(int[] height) {
        int L = 0, R = height.length - 1, ans = 0;
        while (L < R) {
            int h = Math.min(height[L], height[R]);
            ans = Math.max(ans, h * (R - L));
            if (height[L] < height[R]) {
                L++;
            } else {
                R--;
            }
        }
        return ans;
    }

    /**
     * 题意:字符串中最长无重复字符子串的长度。
     * 思路:滑动窗口 + 字符上次出现位置;遇重复则 left 跳到重复字符后。
     * 复杂度:O(n) / O(Σ) 字符集
     * 易错:left 只能右移(Math.max);字符可用 map 或 int[128]。
     */
    public int lengthOfLongestSubstring(String s) {
        Map<Character, Integer> last = new HashMap<>();
        int left = 0, ans = 0;
        for (int right = 0; right < s.length(); right++) {
            char c = s.charAt(right);
            if (last.containsKey(c)) {
                left = Math.max(left, last.get(c) + 1);
            }
            last.put(c, right);
            ans = Math.max(ans, right - left + 1);
        }
        return ans;
    }

    public static void main(String[] args) {
        ArrayProblems p = new ArrayProblems();

        System.out.println("=== 167 两数之和 II ===");
        System.out.println(Arrays.toString(p.twoSum(new int[]{2, 7, 11, 15}, 9)));
        // 期望 [1, 2]

        System.out.println("=== 11 盛水容器 ===");
        System.out.println(p.maxArea(new int[]{1, 8, 6, 2, 5, 4, 8, 3, 7}));
        // 期望 49

        System.out.println("=== 3 无重复最长子串 ===");
        System.out.println(p.lengthOfLongestSubstring("abcabcbb")); // 3
        System.out.println(p.lengthOfLongestSubstring("bbbbb"));    // 1
        System.out.println(p.lengthOfLongestSubstring("pwwkew"));   // 3
    }
}

platcloud
更新于 2026-07-30
上一篇 列表
下一篇 没有了
评论交流

文档目录