From fb0ca1cdb577d39336d20027506cc12f3a64c7b7 Mon Sep 17 00:00:00 2001 From: tom4649 Date: Sat, 25 Jul 2026 10:51:35 +0900 Subject: [PATCH] step1,2 --- 1472.Design-Browser-History/memo.md | 42 +++++++++++++++++++ 1472.Design-Browser-History/step1_del.py | 26 ++++++++++++ 1472.Design-Browser-History/step1_del_v2.py | 26 ++++++++++++ .../step1_linked_list.py | 37 ++++++++++++++++ .../step1_overwrite.py | 30 +++++++++++++ .../step2_two_stack.py | 29 +++++++++++++ 6 files changed, 190 insertions(+) create mode 100644 1472.Design-Browser-History/memo.md create mode 100644 1472.Design-Browser-History/step1_del.py create mode 100644 1472.Design-Browser-History/step1_del_v2.py create mode 100644 1472.Design-Browser-History/step1_linked_list.py create mode 100644 1472.Design-Browser-History/step1_overwrite.py create mode 100644 1472.Design-Browser-History/step2_two_stack.py diff --git a/1472.Design-Browser-History/memo.md b/1472.Design-Browser-History/memo.md new file mode 100644 index 0000000..b7697d2 --- /dev/null +++ b/1472.Design-Browser-History/memo.md @@ -0,0 +1,42 @@ +# 1472. Design Browser History + +## step1 +まずlistを使ってとく。 + +step1_del.py: 最初にlistの要素を消去することを考えたが、配列のコピーが発生する + +step1_del_v2.py: コピーを防ぐために del を使用 + +step1_overwrite.py: lengthをクラスで管理する + +実行時間的にはstep1_overwrite.pyがもっとも速いが、不要なメモリを解放できることを考えるとstep1_del_v2.pyがもっとも良いと思った。 + +LinkedListを使ってもとく。この場合はGCによってメモリが自然に解放される。ただし、履歴の移動でO(steps)かかる。 + +## step2 + +https://leetcode.com/problems/design-browser-history/solutions/674486/two-stacks-pretty-code-by-interviewrecip-kbz8/ + +two stackを使った解法。履歴の移動でO(steps)かかる。 + +以下の問題でも見たことがある。 + +https://leetcode.com/problems/implement-queue-using-stacks/description/ + +自分で思いつくことができなかった。 + +過去と未来を行き来するような状況で発想できるようにしたい。 + + +https://chromium.googlesource.com/chromium/src/+/main/docs/session_history.md + +実際のブラウザがどうなっているか少し調べた。 + +> Chromium tracks the session history of each tab in NavigationController, using a list of NavigationEntry objects to represent the joint session history items. Each frame creates session history items as it navigates. A joint session history item contains the state of each frame of a page at a given point in time, including things like URL, partially entered form data, scroll position, etc. + +リストとして管理しているようなので、配列の解法が最も近そう + +> Each NavigationEntry uses a tree of FrameNavigationEntries to track this state. + +Webページでは内部に複数のiframeがネストされているので、木構造で管理している + diff --git a/1472.Design-Browser-History/step1_del.py b/1472.Design-Browser-History/step1_del.py new file mode 100644 index 0000000..1f67cd2 --- /dev/null +++ b/1472.Design-Browser-History/step1_del.py @@ -0,0 +1,26 @@ +class BrowserHistory: + + def __init__(self, homepage: str): + self.history = [homepage] + self.index = 0 + + def visit(self, url: str) -> None: + self.history = self.history[:self.index + 1] + self.history.append(url) + self.index += 1 + + def back(self, steps: int) -> str: + self.index = max(0, self.index - steps) + return self.history[self.index] + + def forward(self, steps: int) -> str: + self.index = min(len(self.history) - 1, self.index + steps) + return self.history[self.index] + + + +# 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) diff --git a/1472.Design-Browser-History/step1_del_v2.py b/1472.Design-Browser-History/step1_del_v2.py new file mode 100644 index 0000000..97f041f --- /dev/null +++ b/1472.Design-Browser-History/step1_del_v2.py @@ -0,0 +1,26 @@ +class BrowserHistory: + + def __init__(self, homepage: str): + self.history = [homepage] + self.index = 0 + + def visit(self, url: str) -> None: + del self.history[self.index + 1:] + self.history.append(url) + self.index += 1 + + def back(self, steps: int) -> str: + self.index = max(0, self.index - steps) + return self.history[self.index] + + def forward(self, steps: int) -> str: + self.index = min(len(self.history) - 1, self.index + steps) + return self.history[self.index] + + + +# 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) diff --git a/1472.Design-Browser-History/step1_linked_list.py b/1472.Design-Browser-History/step1_linked_list.py new file mode 100644 index 0000000..d7014c0 --- /dev/null +++ b/1472.Design-Browser-History/step1_linked_list.py @@ -0,0 +1,37 @@ +class Node: + + def __init__(self, val: str): + self.val = val + self.prev = None + self.next = None + + +class BrowserHistory: + + def __init__(self, homepage: str): + self.node = Node(homepage) + + def visit(self, url: str) -> None: + next_node = Node(url) + self.node.next = next_node + next_node.prev = self.node + self.node = next_node + + def back(self, steps: int) -> str: + while steps > 0 and self.node.prev: + self.node = self.node.prev + steps -= 1 + return self.node.val + + def forward(self, steps: int) -> str: + while steps > 0 and self.node.next: + self.node = self.node.next + steps -= 1 + return self.node.val + + +# 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) diff --git a/1472.Design-Browser-History/step1_overwrite.py b/1472.Design-Browser-History/step1_overwrite.py new file mode 100644 index 0000000..d540cff --- /dev/null +++ b/1472.Design-Browser-History/step1_overwrite.py @@ -0,0 +1,30 @@ +class BrowserHistory: + + def __init__(self, homepage: str): + self.history = [homepage] + self.index = 0 + self.length = 1 + + def visit(self, url: str) -> None: + if len(self.history) == self.index + 1: + self.history.append(url) + else: + self.history[self.index + 1] = url + self.index += 1 + self.length = self.index + 1 + + def back(self, steps: int) -> str: + self.index = max(0, self.index - steps) + return self.history[self.index] + + def forward(self, steps: int) -> str: + self.index = min(self.length - 1, self.index + steps) + return self.history[self.index] + + + +# 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) diff --git a/1472.Design-Browser-History/step2_two_stack.py b/1472.Design-Browser-History/step2_two_stack.py new file mode 100644 index 0000000..ba1f3c1 --- /dev/null +++ b/1472.Design-Browser-History/step2_two_stack.py @@ -0,0 +1,29 @@ +class BrowserHistory: + + def __init__(self, homepage: str): + self.back_stack = [homepage] + self.forward_stack = [] + + def visit(self, url: str) -> None: + self.back_stack.append(url) + self.forward_stack = [] + + def back(self, steps: int) -> str: + while steps > 0 and len(self.back_stack) > 1: + self.forward_stack.append(self.back_stack.pop()) + steps -= 1 + return self.back_stack[-1] + + def forward(self, steps: int) -> str: + while steps > 0 and self.forward_stack: + self.back_stack.append(self.forward_stack.pop()) + steps -= 1 + return self.back_stack[-1] + + + +# 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)