From a88006e4d81902e3440aedb637f92500c7a7dace Mon Sep 17 00:00:00 2001 From: LouisFonda Date: Thu, 26 Jun 2025 23:36:36 +0800 Subject: [PATCH] feat: 190,120 --- .../bitwise-operations/190颠倒二进制数.js | 25 +++++++ .../dynamic-planning/120三角形最小路径和.js | 74 +++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 top-interview-leetcode150/bitwise-operations/190颠倒二进制数.js create mode 100644 top-interview-leetcode150/dynamic-planning/120三角形最小路径和.js diff --git a/top-interview-leetcode150/bitwise-operations/190颠倒二进制数.js b/top-interview-leetcode150/bitwise-operations/190颠倒二进制数.js new file mode 100644 index 0000000..5d8ee93 --- /dev/null +++ b/top-interview-leetcode150/bitwise-operations/190颠倒二进制数.js @@ -0,0 +1,25 @@ +/** + * @param {number} n - a positive integer + * @return {number} - a positive integer + */ +/** + * @param {number} n - a positive integer + * @return {number} - reversed bits result + */ +const reverseBits = function (n) { + let res = 0; + + // 一共处理32位 + for (let i = 0; i < 32; i++) { + // 提取最低位(0或1) + const bit = n & 1; + + // 把结果左移一位,为新加入的bit腾位置 + res = (res << 1) | bit; + + // 原数字右移一位(无符号),处理下一位 + n >>>= 1; + } + + return res >>> 0; // 确保返回的是无符号数(防止变负) +}; diff --git a/top-interview-leetcode150/dynamic-planning/120三角形最小路径和.js b/top-interview-leetcode150/dynamic-planning/120三角形最小路径和.js new file mode 100644 index 0000000..6ed3720 --- /dev/null +++ b/top-interview-leetcode150/dynamic-planning/120三角形最小路径和.js @@ -0,0 +1,74 @@ +/** + * @param {number[][]} triangle + * @return {number} + */ +const minimumTotal = function (triangle) { + +}; + +/* +思路: +这是一个典型的「从上到下」的动态规划问题,三角形的每个位置只能由上一层的相邻两个位置转移而来。 + +定义状态: +- dp[i][j] 表示从顶点走到位置 (i, j) 的最小路径和 + +状态转移方程: +- 左边界:dp[i][0] = dp[i-1][0] + triangle[i][0] +- 中间:dp[i][j] = min(dp[i-1][j-1], dp[i-1][j]) + triangle[i][j] +- 右边界:dp[i][i] = dp[i-1][i-1] + triangle[i][i] + +初始化: +- dp[0][0] = triangle[0][0] + +返回值: +- 最后一层中的最小值,即 Math.min(...dp[n - 1]) +*/ +function f1(triangle) { + const n = triangle.length; + const dp = Array.from({ length: n }, (_, i) => Array(i + 1).fill(0)); + dp[0][0] = triangle[0][0]; + + for (let i = 1; i < n; i++) { + const len = triangle[i].length; + + // 左边界,只能从上一行第一个元素来 + dp[i][0] = dp[i - 1][0] + triangle[i][0]; + + // 中间部分,来自上一行的[j - 1] 和 [j] + for (let j = 1; j < len - 1; j++) { + dp[i][j] = Math.min(dp[i - 1][j - 1], dp[i - 1][j]) + triangle[i][j]; + } + + // 右边界,只能从上一行最后一个元素来 + dp[i][len - 1] = dp[i - 1][len - 2] + triangle[i][len - 1]; + } + + return Math.min(...dp[n - 1]); +} + +/* +不重复计算len - 1 + */ +function f2(triangle) { + const n = triangle.length; + const dp = Array.from({ length: n }, (_, i) => Array(i + 1).fill(0)); + dp[0][0] = triangle[0][0]; + + for (let i = 1; i < n; i++) { + const len = triangle[i].length; + const last = len - 1; + // 左边界,只能从上一行第一个元素来 + dp[i][0] = dp[i - 1][0] + triangle[i][0]; + + // 中间部分,来自上一行的[j - 1] 和 [j] + for (let j = 1; j < last; j++) { + dp[i][j] = Math.min(dp[i - 1][j - 1], dp[i - 1][j]) + triangle[i][j]; + } + + // 右边界,只能从上一行最后一个元素来 + dp[i][last] = dp[i - 1][last - 1] + triangle[i][last]; + } + + return Math.min(...dp[n - 1]); +}