1. 数独解决方案验证器
描述: 数独背景
数独是一款在 9x9 网格上玩的游戏。游戏的目标是用 1 到 9 之间的数字填充网格的所有单元格,以便每一列、每一行和九个 3x3 子网格(也称为块)中的每一个都包含从 1 到 9 的所有数字。
编写一个函数 // 接受表示数独板的 2D 数组,如果它是有效的解决方案,则返回 true,否则返回 false。数独板的单元格也可能包含 0,这将代表空单元格。包含一个或多个零的电路板被视为无效解决方案。电路板始终是 9 个单元格乘以 9 个单元格,每个单元格仅包含 0 到 9 之间的整数。
例子
validSolution([
[5, 3, 4, 6, 7, 8, 9, 1, 2],
[6, 7, 2, 1, 9, 5, 3, 4, 8],
[1, 9, 8, 3, 4, 2, 5, 6, 7],
[8, 5, 9, 7, 6, 1, 4, 2, 3],
[4, 2, 6, 8, 5, 3, 7, 9, 1],
[7, 1, 3, 9, 2, 4, 8, 5, 6],
[9, 6, 1, 5, 3, 7, 2, 8, 4],
[2, 8, 7, 4, 1, 9, 6, 3, 5],
[3, 4, 5, 2, 8, 6, 1, 7, 9]
]); // => true
validSolution([
[5, 3, 4, 6, 7, 8, 9, 1, 2],
[6, 7, 2, 1, 9, 0, 3, 4, 8],
[1, 0, 0, 3, 4, 2, 5, 6, 0],
[8, 5, 9, 7, 6, 1, 0, 2, 0],
[4, 2, 6, 8, 5, 3, 7, 9, 1],
[7, 1, 3, 9, 2, 4, 8, 5, 6],
[9, 0, 1, 5, 3, 7, 2, 1, 4],
[2, 8, 7, 4, 1, 9, 6, 3, 5],
[3, 0, 0, 4, 8, 1, 1, 7, 9]
]); // => false
解题思路
如果是正确的数独组合,1~9中九个元素一定分别分布在每行的九个不同的索引位置,所以可以通过每个元素的 九个索引下标之和是否等于36 来判断所有元素的正确性;但是元素正确排序不一定正确,所以还需要通过 一个3X3的元素块中九个随机元素之和是否等于45 来确认排序无误。
代码
function validSolution(board){
// 遍历九个元素
for(let i=0; i < board.length; i++) {
let sum = 0;
let sum1= 0;
// 计算某个元素的九个索引下标和
for(let j=0; j < board.length; j++) {
sum = board[j].findIndex(e => e == i+1) + sum;
}
// 第一个3X3元素块元素和
for(let k=0; k < 3; k++) {
sum1 = board[k][0] + board[k][1] + board[k][2] + sum1
}
if (sum !== 36 || sum1 !== 45) {
return false
}
}
return true
}
2. 有效括号
描述:
编写一个函数,该函数采用一串括号,并确定括号的顺序是否有效。如果字符串有效且无效,则该函数应返回。true false
例子
"()" => true
")(()))" => false
"(" => false
"(())((()())())" => true
解题思路
首先可以创建一个对象将左右括号分别保存该对象中,将属性名为左括号的值设置为1,将属性名为右括号的值设置为-1。然后将随机的一串括号保存在一个数组中,遍历这个数组,通过对象中存的括号属性值来判断括号方向。若值为负数则说明右括号数多于左括号,显然是错误的则返回false,若值为正则进一步判断遍历结束后左右括号数是否相等,相等则返回true,否则返回false。
代码
function validParentheses(parens) {
// 将括号分类设置值
let obj = {"(":1, ")":-1}
// 将传入的括号串依次存入数组
let arr = parens.split('')
let result = 0
for (let i=0; i < arr.length; i++) {
// 比较左右括号数量
result = obj[arr[i]] + result
if( result < 0) {
return false
}
}
return result==0? true:false
}
3. 添加大数字
描述:
编写一个返回两个数字之和的函数。输入数字是字符串,函数必须返回字符串。
- 输入数字很大。
- 输入是仅由数字组成的字符串
- 数字是积极的
例子
add("123", "321"); -> "444"
add("11", "99"); -> "110"
解题思路
当输入两个很大的数字,直接相加显然是不行的。所以其实需要用的小学知识的进位就可以解决了。
代码
function add(a, b) {
// 当两个数字长度不同,用0来填补小数字空缺的位数
let maxlength = Math.max(a.length,b.length);
a = a.padStart(maxlength,'0');
b = b.padStart(maxlength,'0');
let jw = 0;
let sum = '';
// 从个位开始计算
for(let i=maxlength-1; i >=0; i--) {
// 将字符类型转换为数字类型
let xj = parseInt(a[i]) + parseInt(b[i]) + jw;
jw = Math.floor(xj/10)
sum = xj % 10 + sum
}
// 判断循环结束最后的位数值相加是否进位
if (jw == 1) {
return ('1' + sum)
}
return sum
}
4. 查找奇数 int
描述:
给定一个整数数组,找到出现奇数次的整数。
始终只有一个整数出现奇数次。
例子
[7] 应该返回 7,因为它出现了 1 次(这是奇数)。
[0] 应该返回 0,因为它出现了 1 次(这是奇数)。
[1,1,2] 应该返回 2,因为它出现了 1 次(这是奇数)。
[0,1,0,1,0] 应该返回 0,因为它出现了 3 次(这是奇数)。
[1,2,2,3,3,3,4,3,3,3,2,2,1] 应该返回 4,因为它出现了 1 次(这是奇数)。
解题思路
创建一个空对象,将传入的数组的值作为空对象的属性名来保存,出现一次的属性名的值设置为1,重复出现的则进行迭代。最后通过查询该对象的值为奇数项输入属性名。
代码
function findOdd(A) {
let obj = {};
for (val of A) {
// 记录每个数字出现的次数
obj[val]?obj[val]++:obj[val]=1
}
for (k in obj) {
if( obj[k] % 2 !== 0) {
return Number(k)
}
}
}
5. 取一个数字并将其数字相加到连续的幂和
描述:
数字89是第一个具有多个数字的整数,它满足一个特殊的属性。因为这个总和给出相同的数字:89 = 8^1 + 9^2
具有此属性的下一个数字是135:
再次查看此属性: 135 = 1^1 + 3^2 + 5^3
我们需要一个函数来收集这些数字,它可能会收到两个整数一个a一个b,定义范围[a,b](含)并输出满足上述属性的范围内的排序数字列表。
例子
让我们看看一些情况(输入 -> 输出):
1, 10 --> [1, 2, 3, 4, 5, 6, 7, 8, 9]
1, 100 --> [1, 2, 3, 4, 5, 6, 7, 8, 9, 89]
如果范围内没有此类数字[a,b]该函数应输出一个空列表。
90, 100 --> []
解题思路
遍历范围内的各个数字,并将该数字分割成单个元素存入数组,通过原数字与分割后各个元素的幂运算之和是否相等判断该数字是否有效。
代码
function sumDigPow(a, b) {
// 用来保存有效的数字,没有则为空
let arr = []
for( let i=a; i <= b; i++) {
// 将每个数字分割并与原数字相比较
var e = i.toString().split('').reduce((s,x,index) => s + x ** (index+1) ,0)
if (i == e ) {
arr.push(i)
}
}
return arr
}
结语
作为一个前端小白来讲,还有很大的进步空间,虽然我的解题方式可能不是最好的,但是如果可以提供另一种思路供大家参考,也就算ok了。如果有帮助的话就请留下你的赞叭!!谢谢各位大佬。