编程大师-技术-算法-leetcode-1472. 设计浏览器历史记录

你需要实现一个模拟单标签页浏览器历史记录的 BrowserHistory 类,核心要求是高效处理访问新页面(清空前进记录)、后退、前进 三个操作。最适合的方案是用 ArrayList 存储历史记录,配合当前索引定位,所有操作的时间复杂度均为 O(1)(visit 截断操作最坏 O(n),但题目约束下完全够用),且逻辑直观、易于理解。

解题思路

  1. 数据结构选择

    • ArrayList<String> 存储浏览历史(按访问顺序排列),支持随机访问和快速截断;
    • int current 记录当前所在页面的索引(初始为0,对应首页)。
  2. 核心操作逻辑

    操作 实现方式
    初始化 将首页加入历史列表,current 设为0。
    visit(url) 截断 current 之后的所有历史记录(清空前进记录),添加新url,current 移到新索引。
    back(steps) 计算新索引 = Math.max(0, current - steps)(不超过历史起点),更新 current 并返回对应url。
    forward(steps) 计算新索引 = Math.min(history.size()-1, current + steps)(不超过历史终点),更新 current 并返回对应url。

完整Java代码(AC级性能,匹配示例)

java 复制代码
import java.util.ArrayList;
import java.util.List;

public class BrowserHistory {
    // 存储浏览历史记录(按访问顺序)
    private final List<String> history;
    // 当前页面在history中的索引
    private int current;

    // 初始化:首页作为初始历史记录
    public BrowserHistory(String homepage) {
        history = new ArrayList<>();
        history.add(homepage);
        current = 0;
    }

    // 访问新url,清空前进记录
    public void visit(String url) {
        // 步骤1:删除current之后的所有记录(前进记录清空)
        // 比如当前在索引2,历史有[0,1,2,3,4],则删除3、4,保留[0,1,2]
        if (current < history.size() - 1) {
            history.subList(current + 1, history.size()).clear();
        }
        // 步骤2:添加新url,current移到新索引
        history.add(url);
        current = history.size() - 1;
    }

    // 后退steps步,返回最终页面url
    public String back(int steps) {
        // 计算后退后的索引(不能小于0)
        current = Math.max(0, current - steps);
        return history.get(current);
    }

    // 前进steps步,返回最终页面url
    public String forward(int steps) {
        // 计算前进后的索引(不能超过历史记录最后一位)
        current = Math.min(history.size() - 1, current + steps);
        return history.get(current);
    }

    // 测试用例(匹配题目示例)
    public static void main(String[] args) {
        BrowserHistory browserHistory = new BrowserHistory("leetcode.com");
        browserHistory.visit("google.com");     // history: [leetcode, google], current=1
        browserHistory.visit("facebook.com");   // history: [leetcode, google, facebook], current=2
        browserHistory.visit("youtube.com");    // history: [leetcode, google, facebook, youtube], current=3
        System.out.println(browserHistory.back(1)); // 3-1=2 → facebook.com
        System.out.println(browserHistory.back(1)); // 2-1=1 → google.com
        System.out.println(browserHistory.forward(1)); // 1+1=2 → facebook.com
        browserHistory.visit("linkedin.com");   // 截断current=2之后的youtube,添加linkedin → history: [leetcode, google, facebook, linkedin], current=3
        System.out.println(browserHistory.forward(2)); // 3+2=5,但最大是3 → linkedin.com
        System.out.println(browserHistory.back(2)); // 3-2=1 → google.com
        System.out.println(browserHistory.back(7)); // 1-7=-6 → 0 → leetcode.com
    }
}

代码关键部分解释

  1. visit方法的截断逻辑
    • history.subList(current + 1, history.size()).clear()subList 返回的是原列表的视图,clear() 会直接删除原列表中对应范围的元素,高效清空前进记录;
    • 例如当前在索引2(facebook),访问linkedin时,会删除索引3(youtube),再添加linkedin,确保前进记录被清空。
  2. 索引边界处理
    • back 时用 Math.max(0, ...) 确保不后退到首页之前;
    • forward 时用 Math.min(history.size()-1, ...) 确保不前进到未访问的页面。
  3. 性能保障
    • ArrayListget 是 O(1) 随机访问,subList().clear() 是 O(n)(n为截断的元素数),但题目中最多调用5000次方法,且单次截断的元素数有限,实际运行无性能问题。

测试用例执行结果(匹配题目输出)

复制代码
facebook.com
google.com
facebook.com
linkedin.com
google.com
leetcode.com

进阶优化(可选,针对极端场景)

如果需要支持百万级历史记录visit 频繁截断,可改用 LinkedList + 迭代器,但会牺牲随机访问性能。对于题目给定的约束(最多5000次调用),ArrayList 是最优选择。

总结

  1. 核心数据结构:ArrayList 存储历史记录 + 索引定位当前页面,兼顾随机访问和截断效率;
  2. 关键逻辑:visit 时截断前进记录,back/forward 时严格控制索引边界;
  3. 性能:所有操作均为高效操作,完全满足题目5000次调用的约束。
相关推荐
贾斯汀玛尔斯17 分钟前
每天学一个算法-快速排序(Quick Sort)
数据结构·算法
炽烈小老头18 分钟前
【每天学习一点算法 2026/04/16】逆波兰表达式求值
学习·算法
优家数科30 分钟前
水质监测不准?解密云端 TDS 数据建模纠偏算法
算法
木井巳36 分钟前
【递归算法】组合总和
java·算法·leetcode·决策树·深度优先·剪枝
coding者在努力1 小时前
被n整除的n位数
c++·算法
黎阳之光1 小时前
去标签化无感定位技术突破,黎阳之光重构空间定位技术路径
大数据·人工智能·算法·安全·数字孪生
见叶之秋1 小时前
【数据结构】详解二叉树和堆
数据结构·算法
CoovallyAIHub2 小时前
MSD-DETR:面向机车弹簧检测的可变形注意力Detection Transformer
算法·架构
CoovallyAIHub2 小时前
不改权重、不用训练!BEM用背景记忆抑制固定摄像头误检,YOLO/RT-DETR全系有效
算法·架构·github
Struggle_97552 小时前
算法知识-从递归入手三维动态规划
算法·动态规划