最近一年坚持做题了127天!
8月
9月
10月
11月
12月
1月
2月
3月
4月
5月
6月
7月
Less
More
题目类型:全部中心扩展二分查找二叉树分治动态规划双指针哈希表回溯字符串广度优先搜索数学数组滑动窗口矩阵贪心递归链表队列攻克200道题目
73.矩阵置零中等
2026-07-06#矩阵
问题: 给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法 。 示例 1: 输入:matrix = [[1,1,1],[1,0,1],[1,1,1]] 输出:[[1,0,1],[0,0,0],[1,0,1]] 示例 2: 输入:matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]] 输出:[[0,0,0,0],[0,4,5,0],[0,3,1,0]] 回答: function setZeroes(matrix) { const m = matrix.length; const n = matrix[0].length; let firstRowHasZero = false; let firstColHasZero = false; // 检查第一行是否有 0 for (let j = 0; j < n; j++) { if (matrix[0][j] === 0) { firstRowHasZero = true; break; } } // 检查第一列是否有 0 for (let i = 0; i < m; i++) { if (matrix[i][0] === 0) { firstColHasZero = true; break; } } // 用第一行和第一列做标记 for (let i = 1; i < m; i++) { for (let j = 1; j < n; j++) { if (matrix[i][j] === 0) { matrix[i][0] = 0; matrix[0][j] = 0; } } } // 根据标记置零(不包含第一行、第一列) for (let i = 1; i < m; i++) { for (let j = 1; j < n; j++) { if (matrix[i][0] === 0 || matrix[0][j] === 0) { matrix[i][j] = 0; } } } // 处理第一行 if (firstRowHasZero) { for (let j = 0; j < n; j++) { matrix[0][j] = 0; } } // 处理第一列 if (firstColHasZero) { for (let i = 0; i < m; i++) { matrix[i][0] = 0; } } }
57.插入区间中等
2026-07-05#数组
问题: 给你一个 无重叠的 , 按照区间起始端点排序的区间列表 intervals ,其中 intervals[i] = [starti, endi] 表示第 i 个区间的开始和结束,并且 intervals 按照 starti 升序排列。同样给定一个区间 newInterval = [start, end] 表示另一个区间的开始和结束。 在 intervals 中插入区间 newInterval ,使得 intervals 依然按照 starti 升序排列,且区间之间不重叠(如果有必要的话,可以合并区间)。 返回插入之后的 intervals 。 注意 你不需要原地修改 intervals 。你可以创建一个新数组然后返回它。 示例 1: 输入:intervals = [[1,3],[6,9]], newInterval = [2,5] 输出:[[1,5],[6,9]] 示例 2: 输入:intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8] 输出:[[1,2],[3,10],[12,16]] 解释:这是因为新的区间 [4,8] 与 [3,5],[6,7],[8,10] 重叠 回答: var insert = function(intervals, newInterval) { const result = []; let i = 0; const n = intervals.length; // 第一阶段:新区间左边的区间 while (i < n && intervals[i][1] < newInterval[0]) { result.push(intervals[i]); i++; } // 第二阶段:合并所有与新区间重叠的区间 while (i < n && intervals[i][0] <= newInterval[1]) { newInterval[0] = Math.min(newInterval[0], intervals[i][0]); newInterval[1] = Math.max(newInterval[1], intervals[i][1]); i++; } result.push(newInterval); // 第三阶段:新区间右边的区间 while (i < n) { result.push(intervals[i]); i++; } return result; };
N皇后困难
2026-06-21#回溯
问题: 按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。 给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。 每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。 示例 1: 输入:n = 4 输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]] 解释:如上图所示,4 皇后问题存在两个不同的解法。 示例 2: 输入:n = 1 输出:[["Q"]] 回答: function solveNQueens(n) { const result = []; // 用三个 Set 分别记录被占用的列、主对角线、副对角线 const cols = new Set(); const diag1 = new Set(); // row - col const diag2 = new Set(); // row + col // board 记录每一行皇后所在的列索引 const board = new Array(n); function backtrack(row) { // 递归终止:所有行都放完了 if (row === n) { // 将 board 转换成题目要求的字符串数组格式 result.push(buildBoard(board)); return; } // 尝试当前行的每一列 for (let col = 0; col < n; col++) { const d1 = row - col; const d2 = row + col; // 检查是否冲突 if (cols.has(col) || diag1.has(d1) || diag2.has(d2)) { continue; } // 做选择 board[row] = col; cols.add(col); diag1.add(d1); diag2.add(d2); // 递归下一行 backtrack(row + 1); // 撤销选择(回溯) cols.delete(col); diag1.delete(d1); diag2.delete(d2); // board[row] 下一轮会被覆盖 } } // 辅助函数:将 board 转为 ['Q..', '...'] 格式 function buildBoard(board) { const result = []; for (let i = 0; i < n; i++) { const row = new Array(n).fill('.'); row[board[i]] = 'Q'; result.push(row.join('')); } return result; } backtrack(0); return result; }
343.整数拆分中等
2026-06-14#动态规划
问题: 给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k >= 2 ),并使这些整数的乘积最大化。 返回 你可以获得的最大乘积 。 示例 1: 输入: n = 2 输出: 1 解释: 2 = 1 + 1, 1 × 1 = 1。 示例 2: 输入: n = 10 输出: 36 解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。 回答: var integerBreak = function(n) { let dp = new Array(n + 1).fill(0); dp[1] = 1; for (let i = 2; i <= n; i++) { for (let j = 1; j < i; j++) { dp[i] = Math.max(dp[i], j * (i - j), j * dp[i - j]); } } return dp[n]; };
670.最大交换中等
2026-06-13#数学
问题: 给定一个非负整数,你 至多 可以交换一次数字中的任意两位。返回你能得到的最大值。 示例 1 : 输入: 2736 输出: 7236 解释: 交换数字2和数字7。 示例 2 : 输入: 9973 输出: 9973 解释: 不需要交换。 注意: 给定数字的范围是 [0, 10 8 ] 回答: var maximumSwap = function (num) { let arr = String(num).split(''); //右边最大数字位置 let maxpos = arr.length - 1 //p 最左边那个需要交换的位置 q 右边最大数字的最后出现位置 let p = -1, q = 0 for (let i = arr.length - 2; i >= 0; i--) { if (arr[i] > arr[maxpos]) { maxpos = i } else if (arr[i] < arr[maxpos]) { p = i q = maxpos } } if (p === -1) return num; [arr[p], arr[q]] = [arr[q], arr[p]] return Number(arr.join('')) };
400. 第 N 位数字中等
2026-06-09#数学
问题: 给你一个整数 n ,请你在无限的整数序列 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ...] 中找出并返回第 n 位上的数字。 示例 1: 输入:n = 3 输出:3 示例 2: 输入:n = 11 输出:0 解释:第 11 位数字在序列 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... 里是 0 ,它是 10 的一部分。 回答: function findNthDigit(n) { if (n < 10) return n; // 个位数直接返回 let digitLength = 1; let count = 9; let start = 1; while (n > digitLength * count) { n -= digitLength * count; digitLength++; count *= 10; start *= 10; } const num = start + Math.ceil(n / digitLength) - 1; const indexInNum = (n - 1) % digitLength; return Number(String(num)[indexInNum]); }
611. 有效三角形的个数中等
2026-06-08#二分查找
问题: 给定一个包含非负整数的数组 nums ,返回其中可以组成三角形三条边的三元组个数。 示例 1: 输入: nums = [2,2,3,4] 输出: 3 解释:有效的组合是: 2,3,4 (使用第一个 2) 2,3,4 (使用第二个 2) 2,2,3 示例 2: 输入: nums = [4,2,3,4] 输出: 4 回答: 满足三角形的条件:任意两边之和大于第三边 var triangleNumber = function(nums) { nums = nums.sort((a, b) => a - b); let n = nums.length; let count = 0; for (let index = n - 1; index >= 2; index--) { let i = 0; let j = index - 1; while (i < j) { if (nums[i] + nums[j] > nums[index]) { count = count + j - i; j--; } else { i++ } } } return count; };
59. 螺旋矩阵 II中等
2026-06-04#双指针
问题: 给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 示例 1: 输入:n = 3 输出:[[1,2,3],[8,9,4],[7,6,5]] 示例 2: 输入:n = 1 输出:[[1]] 回答: var generateMatrix = function(n) { let res = new Array(n).fill().map(() => { return new Array(n).fill(0) }); let left = 0; let top = 0; let right = n - 1; let bottom = n - 1; let cur = 1; while (top <= bottom && left <= right) { for (let i = left; i <= right; i++) { res[top][i] = cur; cur = cur + 1; } top++; for (let i = top; i <= bottom; i++) { res[i][right] = cur; cur = cur + 1; } right--; if (top <= bottom) { for (let i = right; i >= left; i--) { res[bottom][i] = cur; cur = cur + 1; } } bottom--; if (left <= right) { for (let i = bottom; i >= top; i--) { res[i][left] = cur; cur = cur + 1; } } left++; } return res; };
LCR 136. 删除链表的节点简单
2026-06-04#链表
问题: 给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。 返回删除后的链表的头节点。 示例 1: 输入:head = [4,5,1,9], val = 5 输出:[4,1,9] 解释:给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9. 示例 2: 输入:head = [4,5,1,9], val = 1 输出:[4,5,9] 解释:给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9. 回答: var deleteNode = function(head, val) { let dummy = new ListNode(); dummy.next = head; let cur = dummy; while (cur && cur.next) { if (cur.next.val == val) { cur.next = cur.next.next; } cur = cur.next; } return dummy.next; };
416. 分割等和子集中等
2026-06-03#动态规划
问题: 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。 示例 1: 输入:nums = [1,5,11,5] 输出:true 解释:数组可以分割成 [1, 5, 5] 和 [11] 。 示例 2: 输入:nums = [1,2,3,5] 输出:false 解释:数组不能分割成两个元素和相等的子集。 回答: var canPartition = function(nums) { let sum = nums.reduce((a, b) => a + b, 0); //如果总和为奇数,肯定不能分割 if (sum % 2 != 0) { return false; } let target = sum / 2; let dp = new Array(target + 1).fill(false); dp[0] = true; for (let num of nums) { for (let i = target; i >= num; i--) { if (dp[i - num]) { dp[i] = true; } } if (dp[target]) { return true; } } return dp[target]; };
  • 1
  • 2
  • 3
  • 4
  • 20
assistant