《常见高频算法题 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;
}

📌 六、结语与预告

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

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

相关推荐
展信佳_daydayup32 分钟前
0-1 深度学习基础——文件读取
算法
高斯林.神犇35 分钟前
冒泡排序实现以及优化
数据结构·算法·排序算法
Github项目推荐41 分钟前
跨平台Web服务开发的新选择(5802)
算法·架构
louisgeek41 分钟前
Java UnmodifiableList 和 AbstractImmutableList 的区别
java
回家路上绕了弯1 小时前
深度理解 Lock 与 ReentrantLock:Java 并发编程的高级锁机制
java·后端
青云交1 小时前
Java 大视界 -- Java 大数据在智能教育在线课程互动优化与学习体验提升中的应用(386)
java·大数据·flink·在线课程·智能教育·互动优化·学习体验
期待のcode1 小时前
SpringAOP
java·开发语言·spring
Jolyne_2 小时前
树节点key不唯一的勾选、展开状态的处理思路
前端·算法·react.js
秋难降2 小时前
正则表达式:为什么它成了程序员的 “分水岭”?
python·算法·正则表达式
岁忧2 小时前
(LeetCode 面试经典 150 题) 104. 二叉树的最大深度 (深度优先搜索dfs)
java·c++·leetcode·面试·go·深度优先