《常见高频算法题 Java 解法实战精讲(1):链表与数组》

🔍 常见高频算法题 Java 解法实战精讲(1):链表与数组

🧭 前言:算法面试中的链表与数组

链表和数组作为最基础的数据结构,几乎贯穿所有算法面试题。常见考点包括:

  • 链表:反转、合并、找中点、环检测等
  • 数组:双指针、哈希表处理、滑动窗口、前缀和等

文章目录

  • [🔍 常见高频算法题 Java 解法实战精讲(1):链表与数组](#🔍 常见高频算法题 Java 解法实战精讲(1):链表与数组)
    • [🧭 前言:算法面试中的链表与数组](#🧭 前言:算法面试中的链表与数组)
  • 一、算法面试的核心思维
    • [💡 链表与数组解题框架](#💡 链表与数组解题框架)
    • [⚠️ 复杂度分析要点](#⚠️ 复杂度分析要点)
  • [二、反转链表(Reverse Linked List)](#二、反转链表(Reverse Linked List))
    • [💡 题目描述](#💡 题目描述)
    • [⚙️ 迭代解法(双指针)](#⚙️ 迭代解法(双指针))
    • [🔄 递归解法](#🔄 递归解法)
    • [📊 复杂度对比](#📊 复杂度对比)
  • [三、两数之和(Two Sum)](#三、两数之和(Two Sum))
    • [💡 题目描述](#💡 题目描述)
    • [⚙️ 哈希表解法](#⚙️ 哈希表解法)
    • [⚠️ 常见陷阱](#⚠️ 常见陷阱)
    • [🔄 扩展:三数之和](#🔄 扩展:三数之和)
  • 四、滑动窗口(最长无重复子串)
    • [💡 题目描述](#💡 题目描述)
    • [⚙️ 滑动窗口解法](#⚙️ 滑动窗口解法)
    • [📊 窗口移动示意图](#📊 窗口移动示意图)
    • [⚠️ 复杂度分析](#⚠️ 复杂度分析)
  • 五、题解套路总结
    • [💡 双指针技巧矩阵](#💡 双指针技巧矩阵)
    • [🔄 链表操作模板](#🔄 链表操作模板)
    • [⚡️ 滑动窗口模板](#⚡️ 滑动窗口模板)
  • [📌 六、结语与预告](#📌 六、结语与预告)

一、算法面试的核心思维

💡 链表与数组解题框架

问题类型 链表 数组 双指针 递归 虚拟头节点 双指针 哈希表 滑动窗口 二分查找

⚠️ 复杂度分析要点

复杂度 链表常见解法 数组常见解法
O(1) 指针修改 下标访问
O(n) 遍历 单次遍历
O(n²) 嵌套遍历 暴力搜索
O(nlogn) 归并排序 排序+遍历

二、反转链表(Reverse Linked List)

💡 题目描述

​​输入​​:1 → 2 → 3 → 4 → 5

​​输出​​:5 → 4 → 3 → 2 → 1

⚙️ 迭代解法(双指针)

java 复制代码
public ListNode reverseList(ListNode head) {
    ListNode prev = null;
    ListNode curr = head;
    while (curr != null) {
        ListNode nextTemp = curr.next; // 1. 保存后继节点
        curr.next = prev;              // 2. 反转指针
        prev = curr;                   // 3. 前移prev
        curr = nextTemp;               // 4. 前移curr
    }
    return prev;
}

🔄 递归解法

java 复制代码
public ListNode reverseList(ListNode head) {
    if (head == null || head.next == null) 
        return head;
    
    ListNode newHead = reverseList(head.next); // 递归到末尾
    head.next.next = head;  // 反转指针
    head.next = null;       // 断开原指针
    return newHead;
}

📊 复杂度对比

解法 时间复杂度 空间复杂度 适用场景
迭代 O(n) O(1) 内存受限
递归 O(n) O(n) 代码简洁

三、两数之和(Two Sum)

💡 题目描述

​​输入​​:nums = [2,7,11,15], target = 9

​​输出​​:[0,1] (因为 nums[0] + nums[1] = 9)

⚙️ 哈希表解法

java 复制代码
public int[] twoSum(int[] nums, int target) {
    Map<Integer, Integer> map = new HashMap<>();
    for (int i = 0; i < nums.length; i++) {
        int complement = target - nums[i];
        if (map.containsKey(complement)) {
            return new int[]{map.get(complement), i};
        }
        map.put(nums[i], i); // 存储值-索引对
    }
    throw new IllegalArgumentException("No solution");
}

⚠️ 常见陷阱

java 复制代码
// 错误示范:未处理重复元素
int[] nums = {3, 3};
int target = 6;
// 正确解法:哈希表自动覆盖重复值

🔄 扩展:三数之和

java 复制代码
public List<List<Integer>> threeSum(int[] nums) {
    Arrays.sort(nums); // 先排序 O(nlogn)
    List<List<Integer>> res = new ArrayList<>();
    for (int i = 0; i < nums.length - 2; i++) {
        if (i > 0 && nums[i] == nums[i-1]) continue; // 去重
        int left = i + 1, right = nums.length - 1;
        while (left < right) {
            int sum = nums[i] + nums[left] + nums[right];
            if (sum == 0) {
                res.add(Arrays.asList(nums[i], nums[left], nums[right]));
                while (left < right && nums[left] == nums[left+1]) left++; // 去重
                while (left < right && nums[right] == nums[right-1]) right--; // 去重
                left++;
                right--;
            } else if (sum < 0) {
                left++;
            } else {
                right--;
            }
        }
    }
    return res;
}

四、滑动窗口(最长无重复子串)

💡 题目描述

​​输入​​:"abcabcbb"

​​输出​​:3 (最长无重复子串"abc")

⚙️ 滑动窗口解法

java 复制代码
public int lengthOfLongestSubstring(String s) {
    Map<Character, Integer> map = new HashMap<>();
    int maxLen = 0;
    int left = 0;
    
    for (int right = 0; right < s.length(); right++) {
        char c = s.charAt(right);
        if (map.containsKey(c)) {
            // 关键:左指针跳到重复字符的下一位
            left = Math.max(left, map.get(c) + 1);
        }
        map.put(c, right); // 更新字符位置
        maxLen = Math.max(maxLen, right - left + 1);
    }
    return maxLen;
}

📊 窗口移动示意图

窗口变化 窗口2: ab 窗口1: a 窗口3: abc 窗口4: bca a b c a

⚠️ 复杂度分析

​​时间复杂度​​:O(n) 单次遍历

​​空间复杂度​​:O(min(m, n)) m为字符集大小

五、题解套路总结

💡 双指针技巧矩阵

类型 适用场景 经典例题
同向指针 链表遍历 反转链表
反向指针 有序数组 两数之和
快慢指针 环检测 链表环
滑动窗口 子串问题 无重复最长子串

🔄 链表操作模板

java 复制代码
// 虚拟头节点技巧
ListNode dummy = new ListNode(0);
dummy.next = head;

// 链表遍历模板
ListNode curr = head;
while (curr != null && curr.next != null) {
    // 操作节点
    curr = curr.next;
}

// 链表删除模板
prev.next = curr.next;
curr.next = null;

⚡️ 滑动窗口模板

java 复制代码
public int slidingWindow(String s) {
    Map<Character, Integer> map = new HashMap<>();
    int left = 0, maxLen = 0;
    
    for (int right = 0; right < s.length(); right++) {
        char c = s.charAt(right);
        // 更新窗口状态
        map.put(c, map.getOrDefault(c, 0) + 1);
        
        // 收缩窗口条件
        while (窗口不满足条件) {
            char d = s.charAt(left);
            map.put(d, map.get(d) - 1);
            left++;
        }
        
        // 更新结果
        maxLen = Math.max(maxLen, right - left + 1);
    }
    return maxLen;
}

📌 六、结语与预告

本期我们从 链表 与 数组 两大数据结构出发,精选典型题目进行详解。

下一期我们将聚焦:栈与队列的经典题解,包括有效括号匹配、最小栈、单调栈等。

相关推荐
知兀10 分钟前
【MybatisPlus】后端用枚举类,数据库用tinyint,存在枚举类型转换
java
StockTV12 分钟前
印度股票实时数据 NSE和BSE的实时行情、K 线及指数数据
java·开发语言·spring boot·python
User_芊芊君子15 分钟前
【OpenAI 把 AI 玩明白了】:自主推理 + 动态知识图谱,这 4 个技术突破要颠覆行业
java·人工智能·知识图谱
七颗糖很甜23 分钟前
“十五五”气象发展规划:聚焦五大核心任务
大数据·python·算法
科研前沿30 分钟前
镜像视界浙江科技有限公司的关键技术突破有哪些?
大数据·人工智能·科技·算法·音视频·空间计算
嫩萝卜头儿39 分钟前
2 - 复杂度收尾 + 链表经典OJ
数据结构·算法·链表·复杂度
c++之路1 小时前
C++20概述
java·开发语言·c++20
星马梦缘1 小时前
算法设计与分析 作业二 答案与解析
算法·图论·dfs·bfs·floyd-warshall·bellman_ford·多源最短路
玛丽莲茼蒿1 小时前
Leetcode hot100 每日温度【中等】
算法·leetcode·职场和发展
Championship.23.241 小时前
Linux Top 命令族深度解析与实战指南
java·linux·服务器·top·linux调试