Skip to content

Commit d1275c5

Browse files
committed
[Feature] add for new
1 parent 96fd18e commit d1275c5

File tree

2 files changed

+237
-0
lines changed

2 files changed

+237
-0
lines changed

T852-binary-search-peek.html

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>LeetCode T852 - 山脉数组的峰顶索引可视化</title>
6+
<style>
7+
body {
8+
font-family: "Segoe UI", sans-serif;
9+
margin: 0;
10+
padding: 20px;
11+
background-color: #f5f5f5;
12+
color: #333;
13+
}
14+
15+
h1 {
16+
text-align: center;
17+
}
18+
19+
.input-section {
20+
text-align: center;
21+
margin-bottom: 20px;
22+
}
23+
24+
input[type="text"] {
25+
width: 360px;
26+
padding: 8px;
27+
font-size: 16px;
28+
margin-right: 10px;
29+
}
30+
31+
button {
32+
padding: 10px 20px;
33+
font-size: 16px;
34+
margin: 5px;
35+
cursor: pointer;
36+
}
37+
38+
.array {
39+
display: flex;
40+
justify-content: center;
41+
flex-wrap: wrap;
42+
margin: 20px auto;
43+
}
44+
45+
.box {
46+
width: 40px;
47+
height: 40px;
48+
margin: 4px;
49+
line-height: 40px;
50+
text-align: center;
51+
background-color: lightgray;
52+
border-radius: 6px;
53+
position: relative;
54+
font-weight: bold;
55+
}
56+
57+
.box.left, .box.m1 { background-color: #a0d911; }
58+
.box.mid { background-color: #69c0ff; }
59+
.box.right, .box.m2 { background-color: #ff7875; }
60+
61+
.label {
62+
font-size: 12px;
63+
position: absolute;
64+
top: -18px;
65+
width: 100%;
66+
text-align: center;
67+
}
68+
69+
.log {
70+
background-color: #fff;
71+
padding: 15px;
72+
border: 1px solid #ccc;
73+
width: 80%;
74+
margin: 0 auto;
75+
height: 200px;
76+
overflow-y: auto;
77+
font-family: monospace;
78+
}
79+
80+
a {
81+
display: block;
82+
text-align: center;
83+
margin-top: 20px;
84+
text-decoration: none;
85+
color: #1890ff;
86+
}
87+
</style>
88+
</head>
89+
<body>
90+
91+
<h1>📈 LeetCode T852 - 山脉数组峰顶索引可视化</h1>
92+
93+
<div class="input-section">
94+
<input type="text" id="inputArray" value="1,3,5,7,6,4,2" placeholder="输入数组,例如 1,3,5,7,6,4,2" />
95+
<button onclick="startBinary()">二分查找</button>
96+
<button onclick="startTernary()">三分查找</button>
97+
</div>
98+
99+
<div class="array" id="array"></div>
100+
101+
<div class="log" id="log"></div>
102+
103+
<a href="index.html">← 返回首页</a>
104+
105+
<script>
106+
let arr = [];
107+
const arrayEl = document.getElementById("array");
108+
const logEl = document.getElementById("log");
109+
const inputEl = document.getElementById("inputArray");
110+
let timer;
111+
112+
function renderArray(l = -1, m = -1, r = -1, mode = "none") {
113+
arrayEl.innerHTML = "";
114+
arr.forEach((val, i) => {
115+
const box = document.createElement("div");
116+
box.className = "box";
117+
118+
if (mode === "binary") {
119+
if (i === l) box.classList.add("left");
120+
if (i === m) box.classList.add("mid");
121+
if (i === r) box.classList.add("right");
122+
} else if (mode === "ternary") {
123+
if (i === l) box.classList.add("m1");
124+
if (i === r) box.classList.add("m2");
125+
}
126+
127+
const label = document.createElement("div");
128+
label.className = "label";
129+
130+
if (mode === "binary") {
131+
if (i === l) label.innerText = "left";
132+
if (i === m) label.innerText = "mid";
133+
if (i === r) label.innerText = "right";
134+
} else if (mode === "ternary") {
135+
if (i === l) label.innerText = "m1";
136+
if (i === r) label.innerText = "m2";
137+
}
138+
139+
box.innerText = val;
140+
box.appendChild(label);
141+
arrayEl.appendChild(box);
142+
});
143+
}
144+
145+
function log(msg) {
146+
logEl.innerHTML += `<div>> ${msg}</div>`;
147+
logEl.scrollTop = logEl.scrollHeight;
148+
}
149+
150+
function reset() {
151+
clearInterval(timer);
152+
logEl.innerHTML = "";
153+
try {
154+
arr = inputEl.value.split(",").map(s => parseInt(s.trim(), 10));
155+
if (arr.some(isNaN)) throw Error("Invalid number");
156+
} catch {
157+
alert("⚠️ 输入格式错误,请使用英文逗号分隔的整数,例如:1,3,5,7,6");
158+
arr = [1, 3, 5, 7, 6, 4, 2];
159+
inputEl.value = arr.join(",");
160+
}
161+
renderArray(); // 初始渲染
162+
}
163+
164+
function startBinary() {
165+
reset();
166+
let left = 0, right = arr.length - 1;
167+
168+
timer = setInterval(() => {
169+
if (left >= right) {
170+
log(`✅ 找到峰值索引:${left},值为 ${arr[left]}`);
171+
renderArray(left, left, right, "binary");
172+
clearInterval(timer);
173+
return;
174+
}
175+
176+
const mid = Math.floor((left + right) / 2);
177+
renderArray(left, mid, right, "binary");
178+
log(`left=${left}, mid=${mid}, right=${right}, arr[mid]=${arr[mid]}, arr[mid+1]=${arr[mid + 1]}`);
179+
180+
if (arr[mid] < arr[mid + 1]) {
181+
log("➡️ 上升,移动 left = mid + 1");
182+
left = mid + 1;
183+
} else {
184+
log("⬅️ 下降,移动 right = mid");
185+
right = mid;
186+
}
187+
}, 1000);
188+
}
189+
190+
function startTernary() {
191+
reset();
192+
let l = 0, r = arr.length - 1;
193+
194+
timer = setInterval(() => {
195+
if (r - l <= 2) {
196+
let maxIdx = l;
197+
for (let i = l + 1; i <= r; i++) {
198+
if (arr[i] > arr[maxIdx]) maxIdx = i;
199+
}
200+
renderArray(maxIdx, maxIdx, maxIdx);
201+
log(`✅ 峰值索引为 ${maxIdx},值为 ${arr[maxIdx]}`);
202+
clearInterval(timer);
203+
return;
204+
}
205+
206+
const m1 = l + Math.floor((r - l) / 3);
207+
const m2 = r - Math.floor((r - l) / 3);
208+
renderArray(m1, -1, m2, "ternary");
209+
log(`l=${l}, m1=${m1}, m2=${m2}, r=${r}, arr[m1]=${arr[m1]}, arr[m2]=${arr[m2]}`);
210+
211+
if (arr[m1] < arr[m2]) {
212+
log("➡️ 上升趋势,l = m1");
213+
l = m1;
214+
} else {
215+
log("⬅️ 下降趋势,r = m2");
216+
r = m2;
217+
}
218+
}, 1000);
219+
}
220+
221+
// 页面加载时默认初始化
222+
window.onload = () => {
223+
inputEl.value = "1,3,5,7,6,4,2";
224+
arr = inputEl.value.split(",").map(s => parseInt(s.trim(), 10));
225+
renderArray();
226+
};
227+
</script>
228+
229+
</body>
230+
</html>

index.html

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,13 @@ <h1>算法可视化 · 资源导航</h1>
158158
<a href="./T704-binary-search-basic.html" target="_blank">打开页面</a>
159159
</div>
160160

161+
<div class="card" data-tags="T852 binary search 二分查找 三分查找">
162+
<div class="card-title">T852 二分查找峰值、三分查找</div>
163+
<div class="card-desc">通过动画步骤演示二分查找峰值</div>
164+
<a href="./T852-binary-search-peek.html" target="_blank">打开页面</a>
165+
</div>
166+
167+
161168

162169
</div>
163170

0 commit comments

Comments
 (0)