1.删除数组重复项

目的:升序数组去重,不创建新数组,原地删除
思路:
- 双指针遍历数组,left从0不动,right从0开始遍历
- 如果left === right,则right继续遍历,否则left后移一位,将right指向的值赋给left,right继续遍历
保证数组的前left均不相同,且按顺序排列,即前left项去重
function (nums) {let left = 0;let right = 0;if (!Array.isArray(nums)) return;for (let i = right; right < nums.length; right++) {if (nums[left] !== nums[right]) {nums[++left] = nums[right];}}return nums.slice(0, left + 1);};let nums = [0, 0, 1, 1, 1, 2, 2, 3, 3, 4];console.log(removeDuplicates(nums)); // [0, 1, 2, 3, 4]
2.买卖股票的最佳时机 II

目的:给一个数组,按照买卖股票思路,计算最大的收益值
思路:其实就是计算后一项减前一项的差值,max就是差为正值的和
var maxProfit = function(prices) {let max = 0if (prices.length === 0) {return 0}for (let i=0; i<prices.length; i++) {if ((prices[i+1] - prices[i]) > 0) {max += (prices[i+1] - prices[i])}}return max}
3.旋转数组

目的:将数组的每一项都向后移动k位,如果大于length,则从第一位开始
思路:
- 创建一个newArr与原数组一致
- 遍历newArr,将i向前移动放回原数组
关键在于向前移动后的index值为:(i + k) % length
function (nums, k) {let res = [];for (let i = 0; i < nums.length; i++) {res[i] = nums[i];}// 放回原数组,并且 i 超前移动 k 位for (let i = 0; i < res.length; i++) {nums[(i + k) % res.length] = res[i];}};
4.存在重复数组(判断是否有重复)
var containsDuplicate = function (nums) {let map = new Map();if (!Array.isArray(nums)) return;return nums.some((item) => {if (map.has(item)) {return true;} else {map.set(item, true);}});};

5.只出现一次的数字

目的:查找数组中只出现一次的值
思路:
- 设置一个Map对象,记录数组的item,以及出现的次数
遍历map对象,找到value为1的key
var singleNumber = function (nums) {let map = new Map();let res = null;if (Array.isArray(nums)) {nums.forEach((item) => {// 如果map存在该项if (map.has(item)) {let count = map.get(item);map.set(item, ++count);} else {map.set(item, 1);}});map.forEach((value, key) => {if (value === 1) {res = key;}});}return res;};
6.两个数组的交集

目的:求两个数组的交集,并且保证出现的数量一致
思路:用一个hashMap记录num1的item,以及出现的次数
- 遍历num2,如果map上存在就把count—,并且push该item到res
var intersect = function (nums1, nums2) { let map = new Map(); let res = [] nums1.forEach((item) => { if (map.has(item)) { let count = map.get(item); map.set(item, ++count); } else { map.set(item, 1); } }); nums2.forEach(item => { if (map.has(item)) { let count = map.get(item) count > 0 && res.push(item) map.set(item, --count) } }) return res };
7.加一

方法一:通过join方式转化为字符串,再通过BigInt转化为数字,最后转化为number数组
注意:
- 使用BigInt是因为,Number只能转化2^53以内的数字
- BigInt类型只能和BigInt类型相加
var plusOne = function (digits) { let res = []; if (!Array.isArray(digits)) return; let num = BigInt(digits.join("")) + BigInt(1); String(num) .split("") .forEach((item) => res.push(Number(item))); return res; };
方法二:从后往前遍历,从最末位开始+1,如果有一位小于10则return,如果直到遍历接受都没有小于10,说明是999, 9999,这种数字,则数组头部补上一个1
function (digits) {
for (let i = digits.length - 1; i >= 0; i--) {
if (digits[i] + 1 < 10) {
digits[i] = digits[i] + 1;
return digits;
} else {
digits[i] = 0;
}
}
digits.unshift(1)
return digits
};
8.移动0

目的:将数组中所有的0往后移动,不创建新数组,原地移动
思路:双指针法
- 创建right 指针遍历数组,找到非0的item
- 创建left指针,从第一位开始,如果right位不为0,则与right位交换位置
- 因为left和right同时从0开始,所以如果两项都不为0,交换相当于不变,并且left和right均+1
- 如果突然right为0了,说明此时left也为0了,那么left不会向前进,先等right继续前进
- 等到right不为0的时候,交换left和right的值,left+1
var moveZeroes = function (nums) { let left = 0 for (let right = 0; right < nums.length; right++) { if (nums[right] !== 0) { let temp = nums[left] nums[left] = nums[right] nums[right] = temp left++ } } return nums };
9.两数之和

方法1:
- 通过hashMap方式,遍历nums,记录item以及 item 的index值
- 再次遍历nums,查找map中是否hash target-num
方法2:每次遍历时,截取后部分数组,查找是否indexOf > -1function (nums, target) { let map = new Map(); nums.forEach((item, index) => map.set(item, index)); for (let i = 0; i < nums.length; i++) { if (map.has(target - nums[i])) { let j = map.get(target - nums[i]); if (j !== i) { return [i, j]; } } } };
关键在于:nums.slice(i+1)是后部分数组function (nums, target) { for (let i = 0; i < nums.length; i++) { let t = target - nums[i]; let j = nums.slice(i + 1).indexOf(t); if (j > -1) { return [i, j + i + 1]; } } };
10.有效的数独

思路:
- for for 遍历二维数组,获取到对应的行 i, 列 j, num
- 通过 row 记录 i 行的值,判断是否存在重复
- 通过 col 记录 j 列的值,判断是否存在重复
- 将数组分为
1, 2, 3
4, 5, 6
7, 8, 9
九个区域,作为 boxIndex,设置box记录每个box的key,判断是否存在重复
function (board) {
// 记录是否存在相同的值
let row = {};
let col = {};
let box = {};
// 遍历行
for (let i = 0; i < board.length; i++) {
// 遍历列
for (let j = 0; j < board[i].length; j++) {
let num = board[i][j];
// num = . 时不记录到 col
if (num === ".") {
continue;
}
// 计算 boxIndex,将数独分为
// 1, 2, 3
// 4, 5, 6
// 7, 8, 9
// 九个模块,每个模块添加 boxIndex + num 为唯一 key
let boxIndex = Math.floor(i / 3) * 3 + Math.floor(j / 3); // 每三行,模块会多3
// 判断 同一row, col, box 中是否存在相同的值
if (row[i + "" + num] || col[j + "" + num] || box[boxIndex + "" + num]) {
return false;
}
// row 添加 行号+num 作为 key
row[i + "" + num] = true;
// col 添加 列号+num 作为 key
col[j + "" + num] = true;
box[boxIndex + "" + num] = true;
}
}
return true;
};
