目录
刷题思路:按照标签,从简单到困难,依次刷过去。
数组
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.
};
栈
20.有效的括号
155.最小栈
// An highlighted block
/**
* initialize your data structure here.
*/
var MinStack = function() {
this.valueStack = [];
this.minStack = [];
};
/**
* @param {number} x
* @return {void}
*/
MinStack.prototype.push = function(x) {
this.valueStack.push(x);
if(this.minStack.length === 0 || x < this.getMin()){
this.minStack.push({
val:x,
start:this.valueStack.length
})
}
};
/**
* @return {void}
*/
MinStack.prototype.pop = function() {
if(this.top() === this.getMin() && this.minStack.length > 0 && this.minStack[this.minStack.length-1].start === this.valueStack.length){
this.minStack.pop();
}
this.valueStack.pop();
};
/**
* @return {number}
*/
MinStack.prototype.top = function() {
return this.valueStack[this.valueStack.length-1];
};
/**
* @return {number}
*/
MinStack.prototype.getMin = function() {
if(this.minStack.length === 0){
return this.valueStack[0];
}
return this.minStack[this.minStack.length-1].val;
};
225.用队列实现栈
/**
* Initialize your data structure here.
*/
var MyStack = function() {
this.valueStack = [];
};
/**
* Push element x onto stack.
* @param {number} x
* @return {void}
*/
MyStack.prototype.push = function(x) {
this.valueStack.push(x);
};
/**
* Removes the element on top of the stack and returns that element.
* @return {number}
*/
MyStack.prototype.pop = function() {
return this.valueStack.pop();
};
/**
* Get the top element.
* @return {number}
*/
MyStack.prototype.top = function() {
return this.valueStack[this.valueStack.length-1];
};
/**
* Returns whether the stack is empty.
* @return {boolean}
*/
MyStack.prototype.empty = function() {
return this.valueStack.length === 0;
};
682.棒球比赛
/**
* @param {string[]} ops
* @return {number}
*/
var calPoints = function(ops) {
var nums = [];
for(var op of ops){
switch(op){
case '+':
nums.push(Number(nums[nums.length - 1]) + Number(nums[nums.length - 2]));
break;
case 'D':
nums.push(nums[nums.length-1] * 2);
break;
case 'C':
nums.pop();
break;
default:
nums.push(op);
}
}
var sum = 0;
for (var num of nums) {
sum += parseInt(num);
}
return sum;
};
844. 比较含退格的字符串
/**
* @param {string} S
* @param {string} T
* @return {boolean}
*/
var backspaceCompare = function(S, T) {
this.sStack = [];
this.tStack = [];
for(var i = 0; i< S.length; i++){
if(S[i] === '#' && this.sStack.length >0){
this.sStack.pop();
}else{
if(S[i] !== '#'){
this.sStack.push(S[i]);
}
}
}
for(var i = 0; i< T.length; i++){
if(T[i] === '#' && this.tStack.length >0){
this.tStack.pop();
}else{
if(T[i] !== '#'){
this.tStack.push(T[i]);
}
}
}
if(this.sStack.join() == this.tStack.join()){
return true;
}
return false;
};
//其他人的做法
var backspaceCompare = function(S, T) {
return backspace(S) == backspace(T);
};
function backspace(str) {
let backspaceStr = '';
for(let i = 0;i < str.length;i++) {
backspaceStr = str[i] != "#" ? backspaceStr + str[i] : backspaceStr.slice(0,-1);
}
return backspaceStr;
}
331. 验证二叉树的前序序列化
/**
* @param {string} preorder
* @return {boolean}
*/
var isValidSerialization = function(preorder) {
this.dif = 1;
this.arr = preorder.split(',');
for(var i=0;i<this.arr.length; i++){
if(--this.dif < 0){
return false;
}
if(this.arr[i] !== '#'){
this.dif +=2;
}
}
return this.dif == 0;
};
946. 验证栈序列
/**
* @param {number[]} pushed
* @param {number[]} popped
* @return {boolean}
*/
var validateStackSequences = function(pushed, popped) {
let stack = [];
let popIndex = 0;
for (let pushItem of pushed) {
stack.push(pushItem);
while (stack.length && stack.slice(-1)[0] === popped[popIndex]) {
stack.pop();
popIndex ++;
}
}
if (stack.length) {
return false;
} else {
return true;
}
};
71. 简化路径
/**
* @param {string} path
* @return {string}
*/
var simplifyPath = function(path) {
this.pathStack = path.split('/');
this.valueStack = [];
this.shortenPath = '/';
for(var i=0;i<this.pathStack.length;i++){
if(this.pathStack[i]){
if(this.pathStack[i] === '..'){
this.valueStack.pop();
}else if(this.pathStack[i] != '.'){
this.valueStack.push(this.pathStack[i]);
}
}
}
return this.shortenPath + String(this.valueStack.join('/'));
};
856. 括号的分数
链接 (理解不完全)
/**
* @param {string} S
* @return {number}
*/
var scoreOfParentheses = function(S) {
var scoreStack = [];
var c = '';
for(var i=0;i<S.length;i++){
c = S[i];
if(c == '('){
scoreStack.push(-1);
}else{
var score = 0;
while(scoreStack[scoreStack.length-1] != -1){
score += scoreStack.pop();
}
scoreStack.pop();
if(score === 0){
scoreStack.push(1);
}else{
scoreStack.push(2*score);
}
}
}
var totalScore = 0;
for(var i=0;i<scoreStack.length; i++){
totalScore += scoreStack[i];
}
return totalScore;
};
402.移掉K位数字
未实现
901. 股票价格跨度
未通过
var StockSpanner = function() {
this.stackArray = [];
};
/**
* @param {number} price
* @return {number}
*/
StockSpanner.prototype.next = function(price) {
var res = 1;
this.stackArray.push(price);
for(var i=0;i<this.stackArray.length;i++){
if(this.stackArray[i] < price){
res += 1;
}
}
return res;
};
503. 下一个更大元素 II
/** 暴力破解
* @param {number[]} nums
* @return {number[]}
*/
var nextGreaterElements = function(nums) {
this.stackArray = [];
for(var i=0,length=nums.length; i<length; ++i){
this.stackArray.push(-1);
for(var j = i+1; j<length + i; ++j){
var num = nums[j%length];
if(num> nums[i]){
this.stackArray[i] = num;
break;
}
}
}
return this.stackArray;
};
出现延时较长的问题,优化如下:
232. 用栈实现队列
/**
* Initialize your data structure here.
*/
var MyQueue = function() {
this.inbox = [];
this.outbox = [];
};
/**
* Push element x to the back of queue.
* @param {number} x
* @return {void}
*/
MyQueue.prototype.push = function(x) {
this.inbox.push(x);
};
/**
* Removes the element from in front of queue and returns that element.
* @return {number}
*/
MyQueue.prototype.pop = function() {
while (this.inbox.length) {
this.outbox.push(this.inbox.pop());
}
var first = this.outbox.pop();
while (this.outbox.length) {
this.inbox.push(this.outbox.pop());
}
return first;
};
/**
* Get the front element.
* @return {number}
*/
MyQueue.prototype.peek = function() {
return this.inbox[0];
};
/**
* Returns whether the queue is empty.
* @return {boolean}
*/
MyQueue.prototype.empty = function() {
return this.inbox.length === 0;
};
/**
* Your MyQueue object will be instantiated and called as such:
* var obj = Object.create(MyQueue).createNew()
* obj.push(x)
* var param_2 = obj.pop()
* var param_3 = obj.peek()
* var param_4 = obj.empty()
*/