下面的基本上是我个人觉得比较适合陶冶情操、且不伤大脑的 leetcode 的脑筋急「卷」 弯。
这种题最好用 js 写(虽然我用的是 ts),心情和体验都会感到很好的(建议搭配 Quokka.js 插件食用)。
class ListNode {
val,
next,
constructor(val, next) {
this.val = (val === undefined ? 0 : val)
this.next = (next === undefined ? null : next)
}
}
/* 数字字符串 -> 链表 */
const iter = (numbers) => {
const list = numbers.split('')
return list.reduce((a, b) => a = new ListNode(BigInt(b), a), null)
}
/* 链表 -> 数字 */
const parser = (node) => {
const list = []
let temp = node
while (temp !== null) {
list.unshift(temp.val)
temp = temp.next
}
return BigInt(list.join('')) //BigInt 防止大数
}
/* 主函数 */
const addTwoNumbers = (l1, l2) => {
return iter(String(parser(l1) + parser(l2)))
}
// 重点在于 iter & parser 函数的写法,挺简单的一道题
const threeSum = (nums) => {
const list = nums.sort((a, b) => a - b)
const result = []
// 因为只有存在负数或者0的时候,才会三个数的和为0。而且i后面的指针最短为i + 2
for (let i = 0; i < list.length - 2 && list[i] <= 0;i++) {
if (i > 0 && list[i] === list[i - 1]) continue // 防止重复元素重复计算
let j = i + 1
let z = list.length - 1
while (j < z) {
const sum = list[i] + list[j] + list[z]
if (sum === 0) {
result.push([list[i], list[j], list[z]])
j++
z--
// 防止重复
while (j < z && list[j] === list[j - 1]) {
j++
}
while (j < z && list[z] === list[z + 1]) {
z--
}
}else if (sum > 0) {
z--
}else if (sum < 0) {
j++
}
}
}
return result
};
// 双指针老艺术了
// 检查数组是否有效
const check = (list) => !list
.map(e => e === '.' ? 0 : Number(e)) // ‘.‘ 转 0
.sort((a, b) => a - b) // 排序,准备检查是否重复(非 0 的重复)
.some((item, index, array) => index > 0 && item != 0 && item === array[index - 1])
const isValidSudoku = (board) => {
for (let i = 0; i < 9; i++) {
const column = [] //列
const block = [] //每个 3 x 3 区块
const row = board[i] //行
for (let j = 0; j < 9; j++) {
column.push(board[j][i])
block.push(board[
Math.floor(i / 3) * 3 + (j % 3)
][
(i % 3) * 3 + Math.floor(j / 3)
])
}
if (!check(row)) {
return false
}
if (!check(column)) {
return false
}
if (!check(block)) {
return false
}
}
return true
};
const gameOfLife = (board: number[][]): void => {
const _board = board.map(a => a.map(b => b)) // 深 拷 贝
for (let i = 0; i < board.length; i++) {
for (let j = 0; j < board[i].length; j++) {
const list = [
[taowa(_board, i - 1, j - 1), taowa(_board, i - 1, j), taowa(_board, i - 1, j + 1)],
[taowa(_board, i, j - 1), _board[i][j], taowa(_board, i, j + 1)],
[taowa(_board, i + 1, j - 1), taowa(_board, i + 1, j), taowa(_board, i + 1, j + 1)],
]
board[i][j] = rush(list)
}
}
}
// 套娃:js 二维数组越界判断
const taowa = (board: number[][], row: number, column: number) => {
try {
return board[row][column] || 0
} catch{
return 0
}
}
// 生命条件判断
const rush = (board: number[][]) => {
let result = board[1][1]
const alive = board
.*reduce*((a, c) => a.concat(c), []) // 扁平化数组
.reduce((acc, cur, idx) => idx != 4 ? acc + cur : acc) // 中心周围的数字累加
if (alive < 2 && board[1][1] === 1) {
result = 0
}
if ((alive === 2 || alive === 3) && board[1][1] === 1) {
result = 1
}
if (alive > 3 && board[1][1] === 1) {
result = 0
}
if (alive === 3 && board[1][1] === 0) {
result = 1
}
return result
}