目录
-
- 数组
-
- 1. Two Sum
- 26. 删除排序数组中的重复项
- 27. 移除元素
- 35. 搜索插入位置
- 53. 最大子序和
- 66. 加一
- 88. 合并两个有序数组
- 118. 杨辉三角
- 119. 杨辉三角 II
- 122. 买卖股票的最佳时机 II
- 167. 两数之和 II - 输入有序数组
- 169. 求众数
- 189. 旋转数组
- 217. 存在重复元素
- 219. 存在重复元素 II
- 268. 缺失数字
- 283.移动零
- 414. 第三大的数
- 239. 滑动窗口最大值
- 448. 找到所有数组中消失的数字
- 485. 最大连续1的个数
- 509. Fibonacci Number
- 532. 数组中的K-diff数对
- 561. 数组拆分 I
- 566. 重塑矩阵
- 581. 最短无序连续子数组
- 605. 种花问题
- 628. 三个数的最大乘积
- 643. 子数组最大平均数 I
- 661. 图片平滑器
- 栈
- 哈希表
- 树
- 二分查找
- trie树
- 位运算
- 动态规划
- 脑筋急转弯
刷题思路:按照标签,从简单到困难,依次刷过去。
数组
1. Two Sum
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function(nums, target) {
for(var i=0,l=nums.length;i<l;i++){
var j = nums.indexOf(target-nums[i]);
if(j != -1 && j != i){
return [i,j];
}
}
return false;
};
//优化后解法
var twoSum = function(nums, target) {
var ans = [];
var exist = {
};
for (var i = 0; i < nums.length; i++){
if (typeof(exist[target-nums[i]]) !== 'undefined'){
return [exist[target - nums[i]], i];
}
exist[nums[i]] = i;
}
};
优化后解法:
26. 删除排序数组中的重复项
/**
* @param {number[]} nums
* @return {number}
*/
var removeDuplicates = function(nums) {
if(nums.length == 0) return 0;
var i = 0;
for(var j = 1; j < nums.length; j++){
if(nums[j] != nums[i]){
i++;
nums[i] = nums[j];
}
}
return i+1;
};
27. 移除元素
/**
* @param {number[]} nums
* @param {number} val
* @return {number}
*/
var removeElement = function(nums, val) {
var i = 0;
for(var j=0,len=nums.length;j<len;j++){
if(nums[j] != val){
nums[i] = nums[j];
i++;
}
}
return i;
};
35. 搜索插入位置
//O(n)
var searchInsert = function(nums, target) {
for(var i=0,len=nums.length; i<len;i++){
if(nums[i] >= target){
return i;
}
}
return len;
};
//优化写法,二分法 O(log n)
var searchInsert = function(nums, target) {
let low = 0,
high = nums.length - 1;
while(low <= high) {
let mid = Math.floor((low + high) / 2);
if(nums[mid] == target) {
return mid;
} else if(nums[mid] > target) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return high + 1;
};
53. 最大子序和
var currentSum = totalSum = nums[0];
for(var i=1; i<nums.length; i++) {
currentSum = Math.max(nums[i], currentSum+nums[i]);
totalSum = Math.max(totalSum, currentSum);
}
return totalSum;
};
//另一种写法,扩展运算符( spread )是三个点(…)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。
var maxSubArray = function(nums) {
for (let i = 1; i < nums.length; i++){
nums[i] = Math.max(nums[i], nums[i] + nums[i - 1]);
}
return Math.max(...nums);
};
66. 加一
var plusOne = function(digits) {
for(var i = digits.length - 1; i >= 0; i--){
if(++digits[i] > 9) digits[i] = 0;
else return digits;
}
digits.unshift(1);
return digits;
};
此题目题意有点水。。
88. 合并两个有序数组
/**
* @param {number[]} nums1
* @param {number} m
* @param {number[]} nums2
* @param {number} n
* @return {void} Do not return anything, modify nums1 in-place instead.
*/
var merge = function(nums1, m, nums2, n) {
this.stack = [];
for(var i=0,j=0;i<nums1.length;){
if(nums1[i] === 0){
if(j == n) break;
this.stack.push(nums2[j]);
j++;
i++;
}else{
if(nums1[i] < nums2[j]){
this.stack.push(nums1[i]);
i+=1;
}else if(nums1[i] > nums2[j]){
this.stack.push(nums2[j]);
j+=1;
}else{
this.stack.push(nums1[i]);
i+=1;
this.stack.push(nums2[j]);
j+=1;
}
}
}
//return this.stack;//该题目仅允许nums1进行操作,不需要返回值。
};
//优化写法
var merge = function(nums1, m, nums2, n) {
var len = m + n;
m--;
n--;
while (len--) {
if (n < 0 || nums1[m] > nums2[n]) {
nums1[len] = nums1[m--];
} else {
nums1[len] = nums2[n--];
}
}
};
118. 杨辉三角
/**
* @param {number} numRows
* @return {number[][]}
*/
var generate = function(numRows) {
var res = [];
for(var i=0;i<numRows;i++){
for(var j=0,arr=[];j<i+1;j++){
if(j == 0 || j == i){
arr.push(1);
}else{
arr.push(res[i-1][[j-1]] + res[i-1][j]);
}
}
res.push(arr);
}
return res;
};
119. 杨辉三角 II
/**
* @param {number} rowIndex
* @return {number[]}
*/
var getRow = function(rowIndex) {
var row = [1];
for(var i = 1; i <= rowIndex; i++){
for(var j = i; j > 0 ; j--){
if(j == i){
row[j] = 1;
}else{
row[j] = row[j-1] + row[j];
}
}
}
return row;
};
Runtime: 68 ms
122. 买卖股票的最佳时机 II
/**
* @param {number[]} prices
* @return {number}
*/
var maxProfit = function(prices) {
var max = 0;
for(let i=1,len=prices.length;i<len;i++){
if(prices[i] > prices[i-1]){
max += prices[i] - prices[i-1];
}
}
return max;
};
可以简单地继续在斜坡上爬升并持续增加从连续交易中获得的利润,而不是在谷之后寻找每个峰值。最后,我们将有效地使用峰值和谷值,但我们不需要跟踪峰值和谷值对应的成本以及最大利润,但我们可以直接继续增加加数组的连续数字之间的差值,如果第二个数字大于第一个数字,我们获得的总和将是最大利润。这种方法将简化解决方案。
Runtime: 76 ms, faster than 59.42% of JavaScript online submissions for Best Time to Buy and Sell Stock II.
167. 两数之和 II - 输入有序数组
/**
* @param {number[]} numbers
* @param {number} target
* @return {number[]}
*/
var twoSum = function(numbers, target) {
var l=numbers.length, i=0, j=l-1;
while (numbers[i]+numbers[j] !== target) {
numbers[i]+numbers[j] < target ? i++ : j--;
}
return [i+1, j+1];
};
Runtime: 72 ms, faster than 64.98% of JavaScript online submissions for Two Sum II - Input array is sorted.
169. 求众数
/**
* @param {number[]} nums
* @return {number}
*/
var majorityElement = function(nums) {
let len = nums.length;
if(len == 1) return nums[0];
nums.sort();
return nums[parseInt(len/2)];
};
//Runtime: 96 ms, faster than 21.26% of JavaScript online submissions for Majority Element.
//其他做法
var majorityElement = function(nums) {
let hash = {
};
for (let num of nums) {
hash[num] = ++hash[num] || 1;
if (hash[num] > nums.length / 2) {
return num;
}
}
//Runtime: 84 ms, faster than 43.82% of JavaScript online submissions for Majority Element.
//TODO 3.分置法(logN)
};
189. 旋转数组
/**
* @param {number[]} nums
* @param {number} k
* @return {void} Do not return anything, modify nums in-place instead.
*/
var rotate = function(nums, k) {
let length = nums.length;
nums = nums.concat(nums); //双倍数组
let count = k%length +1;
let arr = nums.slice(count, count+length);
return arr;
};
//网站上没通过,本地通过了
//别人的做法
var rotate = function(nums, k) {
k = k % nums.length;
if (k === 0 || nums.length === 1) return;
function reverse(start, finish) {
for (let i = start, j = finish - 1; i < Math.floor((start + finish) / 2); i++, j--) {
let temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
reverse(0, nums.length);
reverse(0, k);
reverse(k, nums.length);
};
//Runtime: 92 ms, faster than 57.98% of JavaScript online submissions for Rotate Array.
var rotate = function(nums, k) {
k = k >= nums.length ? k % nums.length : k;
nums.splice(0,nums.length-k).forEach(
el => nums.push(el)
);
};
Runtime: 80 ms, faster than 62.26% of JavaScript online submissions for Rotate Array.
217. 存在重复元素
/**
* @param {number[]} nums
* @return {boolean}
*/
//暴力枚举
var containsDuplicate =