365天算法记录

96 阅读1分钟

每日算法 每天写一两个算法题,免得一准备面试的时候重头再来,机制如我……^ ^ 算法真的是多写多练,没有捷径

Day1:

日期:210327

1.数组

1:数组往右移位k次

#思路:1.非原地排序,另存一个数组
var rotate = function(nums, k) {
    let newArr=[]
    newArr.length=5
    const len=nums.length
    for (let i=0;i<len;i++){
        newArr[(i+k)%len]=nums[i]
    }
    return newArr
};
rotate([1,2,3,4,5,6,7],3)

#思路:1.最后一个放到第一位,剩下的往后移动一位,循环k次

var rotate = function(nums, k) {
    if(nums.length<=k){
        k=k%nums.length
    }
    for(let i=0;i<k;i++){
        let last=nums[nums.length-1]
        for(let j=nums.length-2;j>=0;j--){
            nums[j+1]=nums[j]
        }
        nums[0]=last
    }
    console.log(nums)
};
rotate([1,2,3,4,5,6,7],3)


2.栈

1.给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。(leetcode20)


#思路:
1.边界判断: 先看是否是string
2.存储: stack=[]
2.map
3.for循环 
4.判断:左括号——stack push(map数据) 
5.判断:右括号——stack pop出来并和自己比较, 不一样 return false
6.如果stack长度为0 返回true

/**
 * @param {string} s
 * @return {boolean}
 */
/**
 * @param {string} s
 * @return {boolean}
 */
var isValid = function (s) {
  if (typeof s !== 'string') return false
  const len = s.length, stack = []
  const map = {
    '{': '}',
    '[': ']',
    '(': ')',
  }
  for (let i = 0; i < len; i++) {
    const crt = s[i]
    if(map[crt]) {
      // 为左括号,则将对应右括号push到stack
      stack.push(map[crt])
    }else if(crt !== stack.pop()){
      // 如果是右括号,则出栈对比
      return false
    }
  }
  return stack.length === 0
}

2.设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。(leetcode155)

#思路1.两个栈,一个存储数据,一个存储最小值。每次都存最小值,因为pop一个后,查看最小值

var MinStack = function() {
    this.stack=[]
    this._minStack=[]
};

/** 
 * @param {number} val
 * @return {void}
 */
MinStack.prototype.push = function(val) {
    this.stack.push(val)
    this._minStack.push(Math.min(this._minStack[this._minStack.length-1],val))
};

MinStack.prototype.pop = function() {
    this.stack.pop()
    this._minStack.pop()
};

MinStack.prototype.top = function() {
    return this.stack[[this.stack.length-1]]
};

MinStack.prototype.getMin = function() {
     return this._minStack[[this._minStack.length-1]]
};

3.用栈实现队列(leetcode:232)

#思路:
1.stack1,stack2为了pop和peek使用 pop是最后循环后stack2中pop一个 而 peek是返回stack2的最后一个
2.stack1中push,empty判断两边stack是否都为空就行。

/**
 * Initialize your data structure here.
 */
var MyQueue = function () {
    this.stack1 = []
    this.stack2 = []
};
/**
 * Push element x to the back of queue. 
 * @param {number} x
 * @return {void}
 */
MyQueue.prototype.transferData = function () {
    while (this.stack1.length) {
        this.stack2.push(this.stack1.pop())
    }
   
}
MyQueue.prototype.push = function (x) {
    this.stack1.push(x)
};

/**
 * Removes the element from in front of queue and returns that element.
 * @return {number}
 */
MyQueue.prototype.pop = function () {
    if (!this.stack2.length) {
        this.transferData()
    }
    return this.stack2.pop()
};

/**
 * Get the front element.
 * @return {number}
 */
MyQueue.prototype.peek = function () {
    if (!this.stack2.length) {
        this.transferData()
    }
    return this.stack2[this.stack2.length - 1]
};

/**
 * Returns whether the queue is empty.
 * @return {boolean}
 */
MyQueue.prototype.empty = function () {
    return this.stack1.length === 0 && this.stack2.length===0

};

/**
 * Your MyQueue object will be instantiated and called as such:
 * var obj = new MyQueue()
 * obj.push(x)
 * var param_2 = obj.pop()
 * var param_3 = obj.peek()
 * var param_4 = obj.empty()
 */

4.比较含退格的字符串(leetcode:844)

思路:
1.栈的push和pop思路
2.for循环
3.不等于#的时候存储push
4.等于#的时候直接pop(判断是否为空)

同理 字符串
1.for循环
2.不等于#的时候str+=item
3.等于#的时候str.substring(0,str.length-1)(判断是否为空) 等于截掉最后一个字符串


function stringFor(str, lastStr){
    for (let i = 0; i < str.length; i++) {
        if (str[i] != '#') {
            //stack.push(str[i])
            lastStr+=str[i]
        }else if(str[i] == '#' && lastStr.length){
            //stack.pop(str[i])
            lastStr=lastStr.substring(0,lastStr.length-1)
        }
    }
    return lastStr
}
var backspaceCompare = function (S, T) {
    //let stackS = []
    //let stackT = []
    let lastS=''
    let lastT=''
    //stringFor(S,stackS)
    return stringFor(S,lastS)===stringFor(T,lastT)
};

5.删除字符串中的所有相邻重复项(leetcode:1047)

/**
 * @param {string} S
 * @return {string}
 */
var removeDuplicates = function (S) {
    if (typeof S !== 'string') return false
    let len = S.length;
    var stack=[]

    for (let i = 0; i < len; i++) {
        var lenStack=stack.length
        if(stack[lenStack-1]!==S[i]){
            stack.push(S[i])
        }else if(lenStack) {
            stack.pop()
        }
    }
    return stack.join('')
};

1.使用栈存储

Day2

日期:210328

3.双指针

1.接雨水(leetcode:84)

84:接雨水

思路:
双指针法(我就是看着代码,一个步骤一个步骤写出来,读懂技巧啦~)
1.使用左指针l=0,右指针r=n-1,左侧最高高度l_max,右侧最高高度r_max
2.比如r_max>l_max,就去关注l,并计算接水容量=l_max-自身高度,故res+=l_max-height[l],l++
3.l<=r 退出循环while
4.返回res

/**
 * @param {number[]} height
 * @return {number}
 */
var trap = function (heights) {
    if (heights.length === 0) return 0;

    let n = heights.length; 
    let l_max = heights[0];//左侧最高初始值
    let r_max = heights[n - 1];//右侧最高初始值

    let l = 0//左指针
    let r = n - 1;//右指针
    var res = 0 //记录接水量

    while (l <= r) {
        l_max = Math.max(l_max, heights[l]) //左侧max高度
        r_max = Math.max(r_max, heights[r]) //右侧max高度
        if (l_max < r_max) {
            res += l_max - heights[l]//左max高度-自身高度
            l++ //指针往右移
        } else {
            res += r_max - heights[r]
            r--
        }
    }
    return res
};

Day2

日期:210408

4.merge

1.49. 字母异位词分组

思路:
1.变成同样的key,然后通过map存储数组
2.返回map.values()值


/**
 * @param {string[]} strs
 * @return {string[][]}
 */
var groupAnagrams = function(strs) {
    let map=new Map()
    for(let str of strs){
        let arr=Array.from(str)
        let key=arr.sort().toString()
        let list=map.has(key)?map.get(key):new Array()
        list.push(str)
        map.set(key,list)
    }
    return Array.from(map.values())
};
groupAnagrams(["eat", "tea", "tan", "ate", "nat", "bat"])

2.字母异位词分组(leetcode:49)

思路:
1.while循环common prefix和str[i]比较chartAt[index] 如果一样的话index++
2.prefix=str[i].substring(0,index)
举例:
leet leed led
1.leet & leed 对比 lee 
2.lee & led 对比 le

/**
 * @param {string[]} strs
 * @return {string}
 */
var longestCommonPrefix = function(strs) {
    if(!Array.isArray(strs)){
        return false
    }
    if(strs.length==0){
        return ''
    }
    let prefix=strs[0];
    for(let str of strs){
        prefix=getCommonPrefix(prefix,str)
        if(!prefix){
            break
        }
    }
    return prefix
};
var getCommonPrefix=(str1,str2)=>{
    let length = Math.min(str1.length, str2.length);
    let index=0;
    while(index<length && str1.charAt(index)===str2.charAt(index)){
        index++
    }
    return str1.substring(0,index)
}
longestCommonPrefix(["flower","flow","flight"])