LeetCode的刷题之路(持续更新)


刷题思路:按照标签,从简单到困难,依次刷过去。

数组

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()
 */

猜你喜欢

转载自blog.csdn.net/Csoap2/article/details/84564082