题目是LeetCode第192场周赛的第三题,链接:1472. 设计浏览器历史记录。具体描述为:你有一个只支持单个标签页的浏览器,最开始你浏览的网页是homepage
,你可以访问其他的网站url
,也可以在浏览历史中后退steps
步或前进steps
步。请你实现BrowserHistory
类:
BrowserHistory(string homepage)
,用homepage
初始化浏览器类。void visit(string url)
从当前页跳转访问url
对应的页面。执行此操作会把浏览历史前进的记录全部删除。string back(int steps)
在浏览历史中后退steps
步。如果你只能在浏览历史中后退至多x
步且steps > x
,那么你只后退x
步。请返回后退至多steps
步以后的url
。string forward(int steps)
在浏览历史中前进steps
步。如果你只能在浏览历史中前进至多x
步且steps > x
,那么你只前进x
步。请返回前进至多steps
步以后的url
。示例1:
输入:
["BrowserHistory","visit","visit","visit","back","back","forward","visit","forward","back","back"]
[["leetcode.com"],["google.com"],["facebook.com"],["youtube.com"],[1],[1],[1],["linkedin.com"],[2],[2],[7]]
输出:
[null,null,null,null,"facebook.com","google.com","facebook.com",null,"linkedin.com","google.com","leetcode.com"]
很明显,这道题用栈来解决就很符合要求。这里需要用到两个栈,一个栈backHistory
用来保存回退历史,另一个栈forwardHistory
用来保存前进的历史。具体地说:
visit(url)
时,把访问的url
入backHistory
,同时forwardHistory
清空back(steps)
时,如果steps
大于backHistory.size()-1
(我们需要保证homepage
总是存在于backHistory
中),那么steps
重置为backHistory.size()-1
,然后将backHistory
中栈顶的steps
个url
都加入到forwardHistory
中去,返回backHistory
的栈顶元素forward(steps)
时,如果steps
大于forwardHistory.size()
(因为forwardHistory
可以为空),那么steps
重置为forwardHistory.size()
,然后将forwardHistory
中栈顶的steps
个url
都加入到backHistory
中去,返回forwardHistory
的栈顶元素JAVA版代码如下:
class BrowserHistory {
private Stack backHistory;
private Stack forwardHistory;
public BrowserHistory(String homepage) {
backHistory = new Stack<>();
backHistory.push(homepage);
forwardHistory = new Stack<>();
}
public void visit(String url) {
backHistory.push(url);
while (!forwardHistory.empty()) {
forwardHistory.pop();
}
}
public String back(int steps) {
steps = Math.min(steps, backHistory.size() - 1);
for (int i = 0; i < steps; ++i) {
forwardHistory.push(backHistory.pop());
}
return backHistory.peek();
}
public String forward(int steps) {
steps = Math.min(steps, forwardHistory.size());
for (int i = 0; i < steps; ++i) {
backHistory.push(forwardHistory.pop());
}
return backHistory.peek();
}
}
/**
* Your BrowserHistory object will be instantiated and called as such:
* BrowserHistory obj = new BrowserHistory(homepage);
* obj.visit(url);
* String param_2 = obj.back(steps);
* String param_3 = obj.forward(steps);
*/
提交结果如下:
另一种方法是直接用一个链表保存url
,同时用一个索引变量idx
标识当前访问的位置,这么做除了在visit
的时候需要remove
掉idx
之后的所有url
之外,其他情况下都只需要改变idx
,而不用进行remove
。
JAVA版代码如下:
class BrowserHistory {
private int idx;
private List history;
public BrowserHistory(String homepage) {
idx = 0;
history = new ArrayList<>();
history.add(homepage);
}
public void visit(String url) {
int size = history.size();
int removeCount = size - idx - 1;
for (int i = 0; i < removeCount; ++i) {
history.remove(size - 1 - i);
}
history.add(url);
++idx;
}
public String back(int steps) {
idx = Math.max(0, idx - steps);
return history.get(idx);
}
public String forward(int steps) {
idx = Math.min(idx + steps, history.size() - 1);
return history.get(idx);
}
}
/**
* Your BrowserHistory object will be instantiated and called as such:
* BrowserHistory obj = new BrowserHistory(homepage);
* obj.visit(url);
* String param_2 = obj.back(steps);
* String param_3 = obj.forward(steps);
*/
提交结果如下:
Python版代码如下:
class BrowserHistory:
def __init__(self, homepage: str):
self.history = [homepage]
self.idx = 0
def visit(self, url: str) -> None:
count = len(self.history) - 1 - self.idx
for _ in range(count):
self.history.pop()
self.history.append(url)
self.idx += 1
def back(self, steps: int) -> str:
self.idx = max(0, self.idx - steps)
return self.history[self.idx]
def forward(self, steps: int) -> str:
self.idx = min(len(self.history) - 1, self.idx + steps)
return self.history[self.idx]
# Your BrowserHistory object will be instantiated and called as such:
# obj = BrowserHistory(homepage)
# obj.visit(url)
# param_2 = obj.back(steps)
# param_3 = obj.forward(steps)
提交结果如下: