1.比较版本号
题目:
比较两个版本号 version1 和 version2。
如果 version1 > version2 返回 1,如果 version1 < version2 返回 -1, 除此之外返回 0。
你可以假设版本字符串非空,并且只包含数字和 . 字符。
. 字符不代表小数点,而是用于分隔数字序列。
例如,2.5 不是“两个半”,也不是“差一半到三”,而是第二版中的第五个小版本。
你可以假设版本号的每一级的默认修订版号为 0。例如,版本号 3.4 的第一级(大版本)和第二级(小版本)修订号分别为 3 和 4。其第三级和第四级修订号均为 0。
思路:先用'.'分割字符串,得到数组,然后依次取出数组的第一个元素进行比较。
版本号的是有权重的,前面的权重更大。所以如果前面的版本号大小不一样,那么就能确定两个版本号的大小关系了。如果一样,就取下一个元素,记得去掉重复的0.
时间复杂度:O(m+n),空间复杂度O(m+n)
/**
* @param {string} version1
* @param {string} version2
* @return {number}
*/
var compareVersion = function(version1, version2) {
const v1 = version1.split(".");
const v2 = version2.split(".");
while (v1.length) {
if (!v2.length){
if(+v1.shift()===0){
continue
}
return 1
}
const vn1=+v1.shift()
const vn2=+v2.shift()
if ( vn1 < vn2 ) return -1;
if(vn1>vn2)return 1
}
while(+v2[0] === 0){
v2.shift()
}
return !v2.length ? 0 : -1;
};
2.分数到小数
题目:
给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以字符串形式返回小数。
如果小数部分为循环小数,则将循环的部分括在括号内。
思路:只看小数部分。小数部分其实只需要看出现过的余数,如果余数出现过,那么就说明重复了
时间复杂度:O(n),空间复杂度O(n)
/**
* @param {number} numerator
* @param {number} denominator
* @return {string}
*/
var fractionToDecimal = function(numerator, denominator) {
if (!numerator) return "0";
const flag1 = numerator * denominator > 0 ? "" : "-";
if (numerator < 0) numerator *= -1;
if (denominator < 0) denominator *= -1;
let interG = Math.abs(~~(numerator / denominator));
let fenshu = numerator % denominator;
if (!fenshu) return `${flag1}${interG}`;
const map = new Map();
let res = `${interG}.`;
const stack = [];
while (fenshu) {
if (!map.has(fenshu)) {
map.set(fenshu, stack.length);
} else {
stack.splice(map.get(fenshu), 0, "(");
stack.push(")");
break;
}
fenshu *= 10;
interG = ~~(fenshu / denominator);
stack.push(interG);
fenshu = fenshu % denominator;
}
return `${flag1}${res}${stack.join("")}`;
};
3.二叉搜索树迭代器
实现一个二叉搜索树迭代器。你将使用二叉搜索树的根节点初始化迭代器。
调用 next()
将返回二叉搜索树中的下一个最小的数。
思路:转成中序遍历,然后用下标获取值
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
*/
var BSTIterator = function(root) {
this.index = 0;
this.node = [];
const search = (root) => {
if (!root) return;
search(root.left);
this.node.push(root.val);
search(root.right);
};
search(root)
};
/**
* @return the next smallest number
* @return {number}
*/
BSTIterator.prototype.next = function() {
return this.node[this.index++]
};
/**
* @return whether we have a next smallest number
* @return {boolean}
*/
BSTIterator.prototype.hasNext = function() {
return this.index<this.node.length
};
/**
* Your BSTIterator object will be instantiated and called as such:
* var obj = new BSTIterator(root)
* var param_1 = obj.next()
* var param_2 = obj.hasNext()
*/
4.最大数
题目:给定一组非负整数,重新排列它们的顺序使之组成一个最大的整数。
思路:比较`${a}${b}`和`${b}${a}`的相对大小即可,类似sort()的排序,
时间复杂度:O(nlogn),空间复杂度:O(1)
var largestNumber = function(nums) {
nums = nums.sort((a, b) => {
let S1 = `${a}${b}`;
let S2 = `${b}${a}`;
return S2 - S1;
});
return nums[0] ? nums.join('') : '0';
};
5.重复的DNA序列
题目:
所有 DNA 都由一系列缩写为 A,C,G 和 T 的核苷酸组成,例如:“ACGAATTCCG”。在研究 DNA 时,识别 DNA 中的重复序列有时会对研究非常有帮助。
编写一个函数来查找目标子串,目标子串的长度为 10,且在 DNA 字符串 s 中出现次数超过一次。
思路:把所有长度为10的子串存储,然后计算次数就行
时间复杂度O(n),空间复杂度O(n)
/**
* @param {string} s
* @return {string[]}
*/
var findRepeatedDnaSequences = function(s) {
if (s.length < 11) return [];
let n = s.length, map = new Map(), left = 0, right = 10, res= [];
while (right <= n) {
let cur = s.substring(left, right);
map.set(cur, map.has(cur) ? map.get(cur) + 1 : 1);
left++;
right++;
}
for (let [k, v] of map) {
if (v > 1) res.push(k);
}
return res;
};