leetcode刷题记录——数组

384 阅读5分钟

javascript刷题顺序按照[Leetcode分类顺序表](挂了。。现在就哪里不会刷哪里)(cspiration.com/leetcodeCla…) 👑->VIP题目

数组

√ 27. 移除元素

√ 26. 删除排序数组中的重复项

双指针

× 80. 删除排序数组中的重复项 II

此题看答案了,答案的办法我大概想不出来。。

👑 277. 搜寻名人

× 189. 旋转数组

这题官方给了三种办法,第一种使用额外的数组最好理解,大概看过之后自己可以默写出来。第三种数组翻转也比较好理解,看过之后也可以自己默写出来。while用的时候总是忘记++--,下次要注意。

× 41. 缺失的第一个正数

难题果然不会。哈希表我目前肯定是不会的。枚举那个办法我想到了!所以思路是没问题的。看了评论果然大家都没想到哈希表的办法,心理平衡了,此题先跳过。

√ 299. 猜数字游戏

这题自己做出来了,但是耗费时间有点久。我的思路是:先把两个字符串split存到数组中;先处理相同项,while循环一下,相同的话就deletedelete只会删除值,变成undefined,不会移位。splice则会变更位置);在处理不同的,两个for循环,需判断undefined,使用typeof() != undefined进行判断,也是delete;最后return相加字符串即可。我的办法只能通过但不是最优解,所以还是要看看别人的解法。

√ 134. 加油站

又做出一题,舒服!记录一下我的思路:首先写一个函数,计算汽油差值的和,如果出现负值则break,返回差值和;然后for循环判断,找到油量大于等于消耗量作为开始点,如果差值和大于0,赋值位置,break;否则赋值-1,最后return所赋的值即可。

√ 118. 杨辉三角

这个是数学题,排列组合解决。首先写一个求阶乘的函数;然后用公式n!/m!/(n-m)!即可计算每一项的值,存在数组里;最后把数组存在大数组里。看了答案发现我写的有点复杂,答案没有求阶乘而是把所有都赋值为1,再加。

√ 119. 杨辉三角 II

尝试了上题实例答案中的解法,看时间还没有俺的算阶乘快,但行数比较少。

√ 169. 多数元素

要求出现次数大于总数1/2,可以推出只有一个值,并且肯定存在这个值。我的解法是:首先把数组排序,用arr.sort()方法;然后用双指针,计算差值;差值大于n/2,返回值;如果都不满足则最后一个值即为所求。

内存消耗和时间越来越长了,头疼。

看了别人的办法果然妙,学到了,中位数那个办法真的不错。arr.sort()中最好加上(a,b) => a-b,因为js sort函数遇到的坑,因此要写成arr.sort((a,b) => a-b)

一些新学到的知识

  1. JS向上取整、向下取整、四舍五入等此题是向下取整,用到Math.floor()(地板)。向上取整Math.ceil()(天花板),这样就好记多了。

√ 229. 求众数 II

依旧用的上题解法,看别人的答案有什么摩尔投票法,先码一下之后看。

× 274. H 指数

做错了。看了答案,大概可以默写出来。

√ 275. H 指数 II

因为把前一题答案背下来了。。。。

👑 243. 最短单词距离

👑 244. 最短单词距离II

👑 245. 最短单词距离III

√ 217. 存在重复元素

双指针真是强,此题用双指针做的,和前面思路基本一致。

√ 219. 存在重复元素 II

依旧双指针,中间隔着k。两个for循环。

√ 220. 存在重复元素 III

和上一题解法基本相似。

√ 55. 跳跃游戏

这题其实就是要判断0的位置:1. 0在位置0处,如果长度大于1就返回false,否则返回true;2. 0在末尾,true;3. 0在中间要看是不是有到0距离小于该位置所在值,是则返回true,否则返回false。

45. 跳跃游戏 II

有点复杂,先放放

× 121. 买卖股票的最佳时机

这题看别人的解法了,自己只能想出两个for循环,结果超时。来写一下我参考的那个答案:首先差初始值为0,买入价格设置为Number.MAX_VALUE;for循环let price of prices,使用Math.min()求出截止到当前遍历最小price,存入买入价中;使用Math.max()求助最大利润,最后返回即可。

一些新学到的知识:

1.Number.MAX_VALUE:javascript中最大的值

× 122. 买卖股票的最佳时机 II

没思路,看答案吧。动态规划or贪心算法。。。 求相邻价格差,大于0则累加到利润中,最后返回利润。

× 123. 买卖股票的最佳时机 III

188. 买卖股票的最佳时机 IV

309. 最佳买卖股票时机含冷冻期

11. 盛最多水的容器

剑指 Offer 03. 数组中重复的数字

  • 方法一:哈希表
    var findRepeatNumber = function(nums) {
        let map = new Map();
        for(let i=0;i<nums.length;i++){
            if(map.has(nums[i])){
                return nums[i]
            } else{
                map.set(nums[i],1)
            }
        }
    };
    
  • 方法二:剑指 Offer中的方法:由题意得数组中数字都在0~n-1的范围内。如果这个数组中没有重复的数字,那么当数组排序之后的数字i将出现在下标为i的位置。
    var findRepeatNumber = function(nums) {
        for(let i=0;i<nums.length;i++){
            while(i !== nums[i]){
                if(nums[i] === nums[nums[i]]) {
                    return nums[i];
                } else{
                    let temp = nums[nums[i]];
                    nums[nums[i]] = nums[i];
                    nums[i] = temp;
                }
            }
        }
    };
    

剑指 Offer 04. 二维数组中的查找

剑指offer04.JPG 使用《剑指Offer》书中的办法,从右上角第一个顶点开始遍历二维数组:如果顶点temp大于target,由于列数据从上到下依次增大,temp是所处列中最小值,由此可知列中无与target相等的值,所以整列删除(也就是列坐标左移);如果temp小于target,由于行数据从左至右依次增大,temp就是当前所处行最大值,因此该行无与target相等的值,遂删除行(行坐标下移)

/**
 * @param {number[][]} matrix
 * @param {number} target
 * @return {boolean}
 */
var findNumberIn2DArray = function(matrix, target) {
    if (!matrix.length) return false
    let i = 0,
        j = matrix[0].length-1;
    while(i<=matrix.length-1 && j>=0){
        const temp = matrix[i][j];
        if(temp > target){
            j -= 1; // 右上顶点比target大,因为右上顶点是该列最小值,所以整列都没有符合条件的值,可以直接缩小范围
        } else if(temp < target){
            i += 1;
        } else{
            return true
        }
    }
    return false
};

Math

× 7. 整数反转

虽然没看答案但是自己查了一些解题思路。 js要注意的点是/除法计算结果并不是整数,这里需要用到parseInt取整数部分才可以。js的指数运算是使用Math.pow(a,b)来计算,结果是ab次幂。还要判断是否溢出

var reverse = function(x) {
    if(x==0) return 0
    let result;
    let count = 0;
    while(x!=0){
        let tail = x % 10;
        result = tail + count * 10;
        if(parseInt((result-tail)/10)!=count) return 0;//判断是否溢出
        x = parseInt(x / 10);
        count = result;
    }
    if(result>=Math.pow(2,31)-1 || result<=Math.pow(-2,31)) return 0
    else return result
};

关于parseInt,需要注意一些问题。

165.

66. 加一

数组转字符串? 递归?

剑指 Offer 09. 用两个栈实现队列

看了书里面的思路才写出来的。。需要注意的就是只有stackB为🈳️,才会将stackA中的数据取出再压入stackB。(这样才能实现队列FIFO的特性

var CQueue = function() {
    this.stackA = []
    this.stackB = []
};

/** 
 * @param {number} value
 * @return {void}
 */
CQueue.prototype.appendTail = function(value) {
    this.stackA.push(value) 
};

/**
 * @return {number}
 */
CQueue.prototype.deleteHead = function() {
    if(!this.stackB.length){
        if(!this.stackA.length) {
            return -1
        } 
        while(this.stackA.length){
            const val = this.stackA.pop()
            this.stackB.push(val)
        }

    } 
    if (this.stackB.length > 0) {
        const val = this.stackB.pop()
        return val  
    } 
    
};

/**
 * Your CQueue object will be instantiated and called as such:
 * var obj = new CQueue()
 * obj.appendTail(value)
 * var param_2 = obj.deleteHead()
 */

剑指 Offer 30. 包含min函数的栈

这题要注意的是利用辅助栈存最小值(是当前最小值),这样辅助栈栈顶元素即当前最小值。

/**
 * initialize your data structure here.
 */
var MinStack = function() {
    this.stack = []
    this.subStack = []
};

/** 
 * @param {number} x
 * @return {void}
 */
MinStack.prototype.push = function(x) {
    this.stack.push(x)
    const SUBL = this.subStack.length
    const subTop = this.subStack[SUBL-1]
    if(SUBL>0 && x>subTop) {   
        this.subStack.push(subTop)
    } else {
        this.subStack.push(x)
    }
        
};

/**
 * @return {void}
 */
MinStack.prototype.pop = function() {
    this.stack.pop()
    this.subStack.pop()
};

/**
 * @return {number}
 */
MinStack.prototype.top = function() {
    const L = this.stack.length
    return this.stack[L-1]
};

/**
 * @return {number}
 */
MinStack.prototype.min = function() {
    const SUBL = this.subStack.length
    return this.subStack[SUBL-1]
};

/**
 * Your MinStack object will be instantiated and called as such:
 * var obj = new MinStack()
 * obj.push(x)
 * obj.pop()
 * var param_3 = obj.top()
 * var param_4 = obj.min()
 */