题目地址:
https://leetcode.com/problems/design-browser-history/
要求设计一个类实现浏览器浏览历史的功能。实现下面的操作:
1、以一个字符串做首页初始化这个对象;
2、访问某个网页,输入是字符串,并且清空前进的历史;
3、回退
s
s
s步,如果
s
s
s大于最大长度,则回退到退无可退的网页,返回字符串;
4、前进
s
s
s步,如果
s
s
s大于最大长度,则前进到进无可进的网页,返回字符串。
法1:用两个栈。维护一个back栈和一个forward栈,维护back栈的栈顶是当前所在的网页。初始化的时候将那个字符串入back栈;访问某个网页,就是将这个网页入back栈,同时清空forward栈(也就是清空前进的历史);回退 s s s步就是将back栈的栈顶出栈,并且push给forward栈,这样的操作重复 s s s次,如果中途back栈空了,就将forward栈栈顶push回给back栈,最后返回back栈栈顶;前进 s s s步也是类似的,从forward栈push给back栈 s s s次,也是返回back栈栈顶。代码如下:
import java.util.Deque;
import java.util.LinkedList;
public class BrowserHistory {
private Deque<String> stackBack, stackForward;
public BrowserHistory(String homepage) {
stackBack = new LinkedList<>();
stackBack.push(homepage);
stackForward = new LinkedList<>();
}
public void visit(String url) {
stackBack.push(url);
stackForward.clear();
}
public String back(int steps) {
while (steps > 0 && !stackBack.isEmpty()) {
stackForward.push(stackBack.pop());
steps--;
}
if (stackBack.isEmpty()) {
stackBack.push(stackForward.pop());
}
return stackBack.peek();
}
public String forward(int steps) {
while (steps > 0 && !stackForward.isEmpty()) {
stackBack.push(stackForward.pop());
steps--;
}
return stackBack.peek();
}
}
back和forward操作时间复杂度 O ( s ) O(s) O(s),空间 O ( n ) O(n) O(n), n n n是总的后退和前进历史的长度。
法2:双向链表。用双向链表可以很直观的解决这道题。visited对应的就是new出next节点同时向后移;back和forward分别对应的就是向前或向后走若干步。代码如下:
public class BrowserHistory {
class ListNode {
String val;
ListNode prev, next;
public ListNode(String val) {
this.val = val;
}
}
private ListNode cur;
public BrowserHistory(String homepage) {
cur = new ListNode(homepage);
}
public void visit(String url) {
cur.next = new ListNode(url);
cur.next.prev = cur;
cur = cur.next;
}
public String back(int steps) {
for (int i = 0; i < steps; i++) {
if (cur.prev != null) {
cur = cur.prev;
} else {
break;
}
}
return cur.val;
}
public String forward(int steps) {
for (int i = 0; i < steps; i++) {
if (cur.next != null) {
cur = cur.next;
} else {
break;
}
}
return cur.val;
}
}
时空复杂度与上同。