当前位置: 代码迷 >> 综合 >> leetcode刷题记录(33)-简单
  详细解决方案

leetcode刷题记录(33)-简单

热度:68   发布时间:2024-02-21 22:50:31.0

1.将数组分成相等的三个部分

题目:

给你一个整数数组 A,只有可以将其划分为三个和相等的非空部分时才返回 true,否则返回 false。

形式上,如果可以找出索引 i+1 < j 且满足 A[0] + A[1] + ... + A[i] == A[i+1] + A[i+2] + ... + A[j-1] == A[j] + A[j-1] + ... + A[A.length - 1] 就可以将数组三等分。

思路:先判断是否能分成相等的三个部分,即和是否能被3整除。

然后,判断成员是否全部为0,为0的话肯定符合条件

最后,双指针,从开头和结尾分别遍历,直到遇到和为三分之一的地方,判断两个指针的大小关系。

为了方便计算,另res[i]=A[0]+...+A[i],这样A[i]+...+A[j]=res[j]-res[i-1],方便计算

/*** @param {number[]} A* @return {boolean}*/
var canThreePartsEqualSum = function(A) {const l = A.length;for (let i = 1; i < l; i++) {A[i] = A[i - 1] + A[i];}if (A[l - 1] % 3) return false;let left = 0;while (left < l) {if (A[left] == A[l - 1] / 3) {break;}left++;}let right = l - 2;while (right > left) {if (A[right] == (2 * A[l - 1]) / 3) {break;}right--;}return right - left >= 1;
};

2.可被5整除的二进制前缀

题目:

给定由若干 0 和 1 组成的数组 A。我们定义 N_i:从 A[0] 到 A[i] 的第 i 个子数组被解释为一个二进制数(从最高有效位到最低有效位)。

返回布尔值列表 answer,只有当 N_i 可以被 5 整除时,答案 answer[i] 为 true,否则为 false。

思路:用parseInt()去解析字符串,很容易就超出最大安全整数了,所以要特别处理一下。可以将数除以10,每次只保留对10的余数,(因为被10整除的数肯定能被5整除),在计算下一位时,乘以2,相当于二进制的下一位

/*** @param {number[]} A* @return {boolean[]}*/
var prefixesDivBy5 = function(A) {const l=A.lengthconst arr = new Array(l);let middle = 0for( var i = 0; i< l; i++){middle = middle * 2 + A[i]arr[i]=!(middle % 5 )middle = middle % 10}return arr};

3.删除最外层的括号

题目:

有效括号字符串为空 ("")、"(" + A + ")" 或 A + B,其中 A 和 B 都是有效的括号字符串,+ 代表字符串的连接。例如,"","()","(())()" 和 "(()(()))" 都是有效的括号字符串。

如果有效字符串 S 非空,且不存在将其拆分为 S = A+B 的方法,我们称其为原语(primitive),其中 A 和 B 都是非空有效括号字符串。

给出一个非空有效字符串 S,考虑将其进行原语化分解,使得:S = P_1 + P_2 + ... + P_k,其中 P_i 是有效括号字符串原语。

对 S 进行原语化分解,删除分解中每个原语字符串的最外层括号,返回 S 。

思路:记录左侧出现的'(',如果是'('且出现的'('数量大于0,说明不是最外层的括号,遇到.)则数量减一.

/*** @param {string} S* @return {string}*/
var removeOuterParentheses = function(S) {let res = '';let v = 0;for(const s of S) {if(s === '(' && v ++ > 0) res += s;if(s === ')' && v -- > 1) res += s;}return res;};

4.从根到页的二进制数之和

题目:

给出一棵二叉树,其上每个结点的值都是 0 或 1 。每一条从根到叶的路径都代表一个从最高有效位开始的二进制数。例如,如果路径为 0 -> 1 -> 1 -> 0 -> 1,那么它表示二进制数 01101,也就是 13 。

对树上的每一片叶子,我们都要找出从根到该叶子的路径所表示的数字。

以 10^9 + 7 为模,返回这些数字之和。

思路:迭代和递归

迭代:

/*** Definition for a binary tree node.* function TreeNode(val, left, right) {*     this.val = (val===undefined ? 0 : val)*     this.left = (left===undefined ? null : left)*     this.right = (right===undefined ? null : right)* }*/
/*** @param {TreeNode} root* @return {number}*/
var sumRootToLeaf = function(root) {if (!root) return 0;const mi = Math.pow(10, 9) + 7;const stack = [{v: "",node: root,},];const res = [];while (stack.length) {const item = stack.pop();if (!item.node) continue;if (!item.node.left && !item.node.right) {res.push(item.v + item.node.val);} else {stack.push({v: item.v + item.node.val,node: item.node.left,});stack.push({v: item.v + item.node.val,node: item.node.right,});}}return res.reduce((res, item) => {res = (res + Number.parseInt(item, 2)) % mi;return res;}, 0);
};

递归:

/*** Definition for a binary tree node.* function TreeNode(val, left, right) {*     this.val = (val===undefined ? 0 : val)*     this.left = (left===undefined ? null : left)*     this.right = (right===undefined ? null : right)* }*/
/*** @param {TreeNode} root* @return {number}*/
var sumRootToLeaf = function(root) {if (!root) return 0;const mi = Math.pow(10, 9) + 7;let sum=0;const search=(root,s='')=>{if(!root)returnif(!root.left&&!root.right){sum+=Number.parseInt(`${s}${root.val}`,2)return}search(root.left,`${s}${root.val}`)search(root.right,`${s}${root.val}`)}search(root)return sum%mi
};

5.除数博弈

题目:

爱丽丝和鲍勃一起玩游戏,他们轮流行动。爱丽丝先手开局。

最初,黑板上有一个数字 N 。在每个玩家的回合,玩家需要执行以下操作:

选出任一 x,满足 0 < x < N 且 N % x == 0 。
用 N - x 替换黑板上的数字 N 。
如果玩家无法执行这些操作,就会输掉游戏。

只有在爱丽丝在游戏中取得胜利时才返回 True,否则返回 False。假设两个玩家都以最佳状态参与游戏。

思路:偶数赢,奇数输

/*** @param {number} N* @return {boolean}*/
var divisorGame = function(N) {
return !(N%2)
};