前言
这周过的真快,又到周末,楼下的树上个星期还黄的灿烂,这周已经只剩下零星。
加班的日子还的继续,实在是自身精力有限。一边写业务,一边改bug,一边还要被插需求,改需求,着实头疼,react的hooks 写的还是少,结合ts的部分目前大部分还是anyscript。突然发现有些时候偷懒偷懒偷着偷着自己就没了,ts的类型定义开发任务太紧,直接any,出现bug是又要仔细去看类型啊。有些技术概念不去理解,即使换成了hooks用起来也还是没有多大提效。有的时候写react 就回出现一种感觉,多了解一些概念,某些组件和业务写起来可以少写几行代码。每到这种时候就很特别的想到,多学理解和学习一些技巧,就可以少些很多代码。然而在某些事情来临时,自己依然选择原路返回。就貌似定义ts类型这个问题,业务一紧急,any吧,一看代码的时候写的什么鬼东西,下次要把类型定义弄上。下次,哈哈。我们的国语还有意思的下次一定。几次之后就明白自己已拉下了。希望接下来的开发中自己能对自己有些要求吧,尽量减少any as的出现。
工具函数
class Node {
constructor(root,left,right){
this.val = root;
this.left = left;
this.right = right;
}
}
// 将数组转换成树
const createTree = (arr) => {
let tree = new Node(arr[0]);
let nodes = [tree];
let i = 1;
for(let node of nodes){
// 没有值返回
if(!node.val) return tree;
nodes.push(node.left = new Node(arr[i]));
i++;
// 遍历完返回
if(i==arr.length) return tree;
nodes.push(node.right = new Node(arr[i]));
i++;
if(i==arr.length) return tree;
}
}
// 获得平方和
function getSumSqrt(n) {
if(!n || isNaN(n)) {
return -1;
}
let s = 0
while(n > 0) {
s = s + (n % 10) * (n % 10);
n = Math.floor(n / 10);
}
return s;
}
二叉树的直径
描述
给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。
解题思路
- 递归结束条件确认 当节点为空的时候返回
- 获取左右节点的最大深度
- 将左右子树的最大深度相加,存入零时变量
- 用临时变量和子树的最大深度比较,取最大的值,重新存入变量
- 返回存入的变量
解:
dianeterOfBinaryTree(root) {
let res = 0;
const dfs = (root) => {
if(!root) {
return 0;
}
// 获取左子树的深度
let left = dfs(root.left);
// 获取右子树的深度
let right = dfs(root.right);
// 存下每次的最深度如果比根节点大覆盖根节点的直径
res = Math.max(res,left + right);
// 每一层加一
return Math.max(left, right)+1;
}
dfs(root);
// 返回二叉树的直径
return res;
}
快乐数
描述
快乐数:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。 如果 可以变为 1,那么这个数就是快乐数。 如果 n 是快乐数就返回 true ;不是,则返回 false
解题思路
- 拆解当前的数 获得平方之和
- 循环平方拆解,最终得到1 则是快乐数
- 否则判断拆解后的平方之和是否存在环中的数字如果存在则不是
- 拆解当前的数 获得平方之和
- 设置快慢指针 快指针走每次走2次,慢指针每次走1次
- 如果快慢指针相等则说明不是快乐数
- 慢指针如果等于1返回结果
解:
isHappy(n) {
let s = n; // 慢
let q = n; // 快
do {
s = getSumSqrt(s);
q = getSumSqrt(q);
q = getSumSqrt(q);
}while(s != q)
return s == 1;
}
有效字母异位词
描述
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
解题思路
- 如果两个字符串长度不一样直接返回false
- 生成26个字母空间并且每个空间设置初始值为0
- 先遍历一次
s串s串中的每个字符每出现一次 累加一次 - 遍历
t串t串每出现一次减一次 如果1中空间中的值有一个小于0 那么说明不是有效字母异位词
解:
isAnagram(s1, s2) {
if(s1.length != s2.length) {
return false;
}
let arr = new Array(26).fill(0);
for(let i = 0; i < s1.length; i++) {
arr[s1.codePointAt(i) - 97]++;
}
for(let j = 0; j < s2.length; j++) {
arr[s2.codePointAt(j) - 97]--;
if(arr[s2.codePointAt(j) - 97] < 0) {
return false;
}
}
return true;
}
桶排序
描述
数据排序已经很长常见了,给定一个乱序的数组,返回从小到到的排序后返回
解题思路
- 确定桶的个数与每个桶的取值范围
- 放入对应在的数范围的数据到对应的桶中,
- 每个桶排序
- 最后顺序读取桶中的内容
解:
sort(arr) {
//生成桶
let min = Math.min(arr[0], ...arr);
let max = Math.max(arr[0], ...arr);
let num = parseInt((max-min) / arr.length) + 1;
let numArr = new Array(num);
for(let i = 0; i < num; i++) {
numArr[i] = new Array
}
// 桶生成完成
// 将对的数放入对应的桶
for(let i = 0; i < arr.length; i++) {
let n = parseInt((arr[i] - min) / arr.length);
numArr[n].push(arr[i]);
}
// 每个桶的自己的排序
for(let i = 0; i < numArr.length; i++) {
numArr[i].sort();
}
//顺序读取桶中
let arrIndex = 0;
for(let i = 0; i < numArr.length; i++) {
for(let j = 0; j < numArr[i].length; j++) {
arr[arrIndex++] = numArr[i][j]
}
}
return arr;
}