leetcode刷题之数组问题总结,二分法,移除元素,滑动窗口相关问题,螺旋矩阵相关问题

本文详细介绍了二分查找在寻找目标值、插入位置以及在有序数组中查找元素范围等问题上的应用,同时也探讨了移除元素(如删除重复项、移动零)的不同策略,包括暴力解法、快慢指针和双向指针。此外,还讨论了处理螺旋矩阵的方法。所有这些算法都展示了如何高效地处理数组和序列数据结构。
摘要由CSDN通过智能技术生成

一、二分查找相关应用

704.二分查找

在这里插入图片描述

var search = function(nums, target) {
    let low = 0,high = nums.length - 1
    let mid = Math.ceil(low + (high - low) /2)
    while(low<=high){
        mid = Math.ceil(low + (high - low) /2)
        if(target==nums[mid]){
            return mid
        }else if(nums[mid]<target){
            //往右走
            low = mid + 1
        }else{
            //往左走
            high = mid - 1
        }
    }
    return -1
};

35.搜索插入位置

在这里插入图片描述

方法一:二分法
var searchInsert = function(nums, target) {
    //二分查找 找到该插入到的位置
    let low = 0,high = nums.length - 1
    let mid = 0
    while(low<=high){
        mid = Math.ceil(low + (high - low)/2)
        if(nums[mid]==target){
            return mid
        }else if(target<nums[mid]){
            //往左走
            high = mid - 1
        }else{
            //往右走
            low = mid + 1
        }
    }
    //当low==high的时候,mid = low = high 还未找到target,if(target<nums[mid]) => high = mid - 1,这时候mid左侧都比target小 故target应该放到mid的位置,if(target>nums[mid]) => low = mid + 1,包括mid和他左侧的都比他小,target应该放入到mid+1的位置 总之返回位置总是high + 1
    return nums[mid]>target?mid:mid+1
};
暴力解法
var searchInsert = function(nums, target) {
    //暴力解法
    let len = nums.length
    for(let i = 0;i<len;i++){
        if(nums[i]==target){
            //找到target了
            return i
        }else if(nums[i]>target){
            //将target放入到nums[i]
            return i
        }
    }
    return len

};

34.在排序数组中查找元素的开始位置和最后一个位置

在这里插入图片描述

方法一:暴力解法
var searchRange = function(nums, target) {
    if(nums==[]) return [-1,-1]
    let start = null,end = null
    for(let i=0;i<nums.length;i++){
        if(nums[i]==target){
            start = i
            break //结束循环
        }
    }
    //倒着来 去找target
    for(let j = nums.length - 1;j>=0;j--){
        if(nums[j]==target){
            end = j
            break
        }
    }
    if(start==null&&end==null){
        return [-1,-1]
    }
    return [start,end]
};
方法二:二分法,确定左右两侧的边界
var searchRange = function(nums, target) {
    //由于数组是递增的 那么如果target有多个的话,一定是相邻的 可以使用二分法来分别找到左右边界
    const getLeftBorder = (nums,target) =>{
        let low = 0,high = nums.length - 1
        let mid = Math.ceil((low+high)/2) //找到中间的下标
        let leftBorder = null//用来记录左边界
        while(low<=high){
            mid = Math.ceil((low+high)/2)
            if(nums[mid]>=target){
                //注意 这里等于的时候也要移动
                high = mid - 1
                leftBorder = high
            }else{
                low = mid + 1
            }
        }
        return leftBorder   //根据循环里面的判断条件,最后跳出循环的时候,high位于范围的左侧
    }

    const getRightBorder = (nums,target) =>{
        let low = 0,high = nums.length - 1
        let mid = Math.ceil((low+high)/2) //找到中间的下标
        let rightBorder = null
        while(low<=high){
            mid = Math.ceil((low+high)/2)
            if(nums[mid]<=target){ //这样才能移动到右侧边界
                low = mid + 1
                rightBorder = low
            }else{
                high = mid - 1
            }
        }
        return rightBorder 
    }

    const left = getLeftBorder(nums,target)
    const right = getRightBorder(nums,target)
    //情况一:nums为空 或者 target不再这个范围内
    if(nums==[]||left==null||right==null){
        return [-1,-1]
    }
    //要保证left与right之间有一个结点
    if(right-left>1){
        return [left+1,right-1]
    } 
    return [-1,-1]
    
};

69.x的平方根

在这里插入图片描述

方法一:二分法
var mySqrt = function(x) {
    //计算并返回x的算术平方根 这里给出的是非负整数
    //除了0之外 别的非负整数的算术平方根的范围是1 到 x
    //里用二分法 从 1 到 x 之间进行判断
    let low = 1,high = x
    let mid = null
    while(low<=high){
        mid = Math.ceil((low+high)/2)
        if(mid*mid<=x){
            if((mid+1)*(mid+1)>x){
                return mid
            }
            low = mid + 1
        }else{
            if((mid-1)*(mid-1)<=x){
                return mid - 1
            }
            high = mid - 1
        }
    }
    //如果在x = 0 那么返回0
    return 0
};
方法二:暴力解法
var mySqrt = function(x) {
    if(x==0) return 0 
    //如果x = 1 那么这个遍历中只有一项 没有i+1 就会出错
    if(x==1) return 1
    for(let i=1;i<x;i++){
        if(i*i<=x&&(i+1)*(i+1)>x){
            return i
        }
    }
};
错解:多次判断,超时了
var mySqrt = function(x) {
    //计算并返回x的算术平方根 这里给出的是非负整数
    //除了0之外 别的非负整数的算术平方根的范围是1 到 x
    //里用二分法 从 1 到 x 之间进行判断
    
    let low = 1,high = x
    let mid = null
    while(low<=high){
        mid = Math.ceil((low+high)/2)
        if(mid*mid<=x&&(mid+1)*(mid+1)>x){
            return mid
        }
        if(mid*mid<x&&(mid+1)*(mid+1)<x){
            //继续往右侧移动
            low = mid + 1
            continue
        }
        if(mid*mid>x&&(mid-1)*(mid-1)<=x){
            return mid - 1
        }
        if(mid*mid>x&&(mid-1)*(mid-1)>x){
            //想左侧移动
            high = mid - 1
            continue
        }
    }
    //如果在x = 0 那么返回0
    return 0
};

367.有效完全平方数

在这里插入图片描述

方法一:暴力解法
var isPerfectSquare = function(num) {
    //正整数num 那么它的平方根一定在 1 到 num之间    这里注意1的平方还是1
    for(let i = 1;i<=num;i++){
        if(i*i==num){
            return true
        }
    }
    return false
};
方法二:二分法
var isPerfectSquare = function(num) {
    //二分法 num的平方根一定在 1 到num之间
    if(num==1) return true
    let low = 1,high = num
    while(low<=high){
        mid = Math.ceil((low+high)/2)
        if(mid*mid==num){
            return true
        }else if(mid*mid<num){
            //要往右走
            low = mid + 1
        }else{
            //往左走
            high = mid - 1
        }
    }
    //未找到
    return false
};

二、移除元素相关

27.移除元素

在这里插入图片描述

方法一:暴力解法
var removeElement = function(nums, val) {
    //题目说了 数组的顺序可以改变
    //对数组进行排序
    nums.sort((a,b)=>a-b)
    //那么val值相同的元素都是相邻的
    let count = 0  //用来记录val的个数
    let start = null  //开始的索引位置

    //找到val的开始位置
    for(let i = 0;i<nums.length;i++){
        if(nums[i]==val){
            start = i
            break//结束循环
        }
    }

    for(let i=0;i<nums.length;i++){
        if(nums[i]==val){
            count++
        }
    }
    nums.splice(start,count)
};

暴力解法2
var removeElement = function(nums, val) {
    //暴力解法二
    let len = nums.length
    //两层for循环 外边的一层是用来找val 里面的for循环用来从后往前移动val
    for(let i=0;i<len;i++){
        if(nums[i]==val){
            //从后往前去移动元素 将当前的nums[i]给替换掉
            for(let j=i;j<len-1;j++){
                nums[j] = nums[j+1]
            }
            //移动元素结束之后 
            len--
            i--//刚刚移动过来的这个元素没有判断,需要判断一下
        }
    }
    return len
};
快慢指针方法
var removeElement = function(nums, val) {
    //快慢指针
    let slow = 0,fast = 0
    //这样就可以只用一个for循环即可
    for(fast;fast<nums.length;fast++){
        if(nums[fast]!==val){    //当遍历到的值不是val时,slow和fast同时移动
            nums[slow++] = nums[fast]  //当遇到的是val,slow会停留在这个val值这里,然后fast向后移动,if fast遇到的这个值不是val,那么slow 和 fast 进行交换 ,else fast遇到的还是val,那么slow还是不动,fast继续移动;由于交换完成之后,slow自动加一,所以最后slow指向数组的末尾的后一个位置
        }
    }
    return slow
};



var removeElement = function(nums, val) {
    //快慢指针
    let slow = 0, fast = 0
    for(;fast<nums.length;fast++){
        if(nums[fast]!==val){
            nums[slow++] = nums[fast]
        }
    }
    //最后slow指向数组的最后一个位置的下一个
    nums.splice(slow)   //将slow后面的元素给移除掉(包括slow这个位置)
};
双向指针
var removeElement = function(nums, val) {
    //从左右两侧进行比较
    let left = 0,right = nums.length - 1
    while(left<=right){
        //左侧指针要找val值
        while(left<=right&&nums[left]!==val){
            ++left
        }
        //右侧指针要找不是val的值
        while(left<=right&&nums[right]==val){
            --right
        }
        //这里曾经有一个错误理解,右侧指针移动的过程中会将等于val的值给忽略过去,最会返回数组长度的时候,要看left 所以这样不会造成影响
        //以上两个while循环结束之后,left指针指向一个等于val的值,right指向一个不等于val的值
        if(left<right){   //if left==right 就没有必要交换了
            nums[left++] = nums[right--]
        }
    }
    //每次结束之后,left都会进行加一,故最后left指向新数组的末尾的下一项
    return left
};



var removeElement = function(nums, val) {
    //双向指针
    let left = 0, right = nums.length - 1
    while(left<=right){
        //left指针找值为val的 right指针找不是val的 我们要做的就是将左侧是val的移动到右侧 进行替换
        while(left<=right&&nums[left]!==val){ //这样这个循环结束之后,left指向等于val的地方
            left++
        }
        while(left<=right&&nums[right]==val){//这样这个循环结束之后,right指向不等于val的地方
            right--
        }
        //两个while循环结束之后,left指向等于val的位置 right指向不等于val的位置
        if(left<right){
            [nums[left],nums[right]] = [nums[right],nums[left]]
            left++
            right--
        }
    }
    nums.splice(left)
    
};

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

在这里插入图片描述

暴力解法
var removeDuplicates = function(nums) {
    //暴力解法
    let len = nums.length
    for(let i = 0;i<len;i++){
        let target = nums[i]
        for(let j = i+1;j<len;j++){
            //从这里开始去找target
            if(nums[j]==target){
                //后面的全部数组向前进行移动
                for(let k=j+1;k<len;k++){
                    nums[k-1] = nums[k]
                }
                //移动一次之后,len--
                len--
                j--
            }
        }
    }
    return len
};
快慢指针
var removeDuplicates = function(nums) {
    //千万要注意,nums是升序的  因为是升序的 所以不会出现 3 4 3的情况
    //使用快慢指针
    let slow = 0,fast = 1
    for(fast;fast<nums.length;fast++){
        if(nums[slow]!==nums[fast]){
            slow++
            nums[slow] = nums[fast]
        }
    }
    //因为slow先加一 然后才会将新的值放入到slow这里 故最后结束的时候 slow指向的是数组的最后的位置
    return slow + 1
};

283.移动零

在这里插入图片描述

错解

使用左右两侧指针会导致元素的顺序发生变化

var moveZeroes = function(nums) {
    //使用双指针 左右两侧指针
    let left = 0,right = nums.length - 1
    while(left<=right){
        //左指针去找0
        while(left<=right&&nums[left]!==0){
            ++left
        }
        //右指针将0忽略
        while(left<=right&&nums[right]==0){
            --right
        }
        //执行完成上面两个while循环之后,left指向0 right不指向0 然后将left与right所指向的值进行交换
        if(left<right){
            nums[left] = nums[right]
            nums[right] = 0
        }
    }
};
快慢指针
var moveZeroes = function(nums) {
    //快慢指针 先将非零元素移动到前面 然后再将后面的元素填补为0
    let slow = 0,fast = 0
    for(fast;fast<nums.length;fast++){
        if(nums[fast]!==0){
            nums[slow++] = nums[fast]
        }
    }
    //上面的for循环完成之后,前面都是非零值   此时slow指向非零部分末尾的下一个位置
    for(let i=slow;i<nums.length;i++){
        //将后面全都填充成0
        nums[i] = 0
    }

};
暴力解法
var moveZeroes = function(nums) {
    //暴力解法
    let len = nums.length
    //外层循环判断每一项是否是0 里面的for循环来移动位置
    for(let i=0;i<len;i++){
        if(nums[i]==0){
            for(let j=i+1;j<len;j++){
                nums[j-1] = nums[j]
            }
            len--
            i--
        } 
    }
    let j = len
    while(j<nums.length){
        nums[j] = 0
        j++
    }
};

844.比较含退格的字符串

题目详情
题解参考

方法一:使用栈 栈是用来解决括号匹配等问题的一大利器
var backspaceCompare = function(s, t) {
    //使用栈
    const helper = str =>{
        let stack = []
        for(let i=0;i<str.length;i++){
            if(str.charAt(i)!=='#'){
                stack.push(str.charAt(i))
            }else{
                stack.pop()
            }
        }
        //结束之后,转换成字符串
        return stack.join()
    }
    const str1 = helper(s)
    const str2 = helper(t)
    if(str1==str2){
        return true
    }else{
        return false
    }

};
方法二:使用指针,从右往左
var backspaceCompare = function(s, t) {
    //使用指针
    let i = s.length - 1
    let j = t.length - 1  //指向字符串的最后一个位置
    let skipS = 0
    let skipT = 0   //用来记录从右往左进行遍历过程中遇到的#号
    //主要思路:对两个字符串同时从右侧往左侧进行遍历,如果遇到#,那么skip加一,如果遇到的不是#,且skip是正数,那么skip减一   直到两个字符串都比较完成
    while(i>=0||j>=0){
        //对字符串s进行统计
        while(i>=0){
            if(s[i]=='#'){
                skipS++   //统计遇到的#个数
                i--   //继续往左侧移动
            }else if(skipS>0){
                skipS--   //用来消除前面的字符串
                i--
            }else{
                break
            }
        }
        //对字符串t进行统计
        while(j>=0){
            if(t[j]=='#'){
                skipT++
                j--
            }else if(skipT>0){
                skipT--
                j--
            }else{
                break
            }
        }
        //如果处理退格之后的字符不相等,返回false
        if(s[i]!==t[j]) return false
        i--
        j--
    }
    return true

};

977.有序数组的平方

在这里插入图片描述

方法一:暴力解法
var sortedSquares = function(nums) {
    //方法:先对每个元素进行平方放入到原来的位置,然后对数组进行排序
    for(let i=0;i<nums.length;i++){
        nums[i] = nums[i]*nums[i]
    }
    nums.sort((a,b)=>a-b)
    return nums
};
方法二:双指针
var sortedSquares = function(nums) {
    //思路:由于数组是递增的,数组平方之后的大小 要以 0 为中心,向两侧逐渐变大
    //故只需要数组首尾两端 然后将大的放到新数组的最后一个位置  这里使用双指针,分别指向数组的首尾
    let i = 0, j = nums.length - 1, last = nums.length - 1
    let arr = new Array(nums.length)
    while(i<=j){
        let leftVal = nums[i] * nums[i]
        let rightVal = nums[j] * nums[j]
        arr[last--] = leftVal<rightVal?(j--,rightVal):(i++,leftVal)
    }
    return arr
};

三、滑动窗口相关问题

209.长度最小的子数组

方法一:暴力解法
var minSubArrayLen = function(target, nums) {
    //暴力解法
    let res = [] //用来记录从当前i开始连续有几个元素
    for(let i=0;i<nums.length;i++){
        let sum = nums[i] //用来保存当前的累加和
        if(sum>=target){ //当前值已经满足条件的了,后面就不用再遍历了
            return 1
        }
        for(let j=i+1;j<nums.length;j++){
            sum+=nums[j]
            if(sum>=target){
                res.push(j-i+1)
                break //结束当前的循环
            }
        }
    }
    if(res.length==0) return 0
    //找出res中最小的
    res.sort((a,b)=>a-b)
    return res[0]
};
暴力解法修改
var minSubArrayLen = function(target, nums) {
    //暴力解法
    let min = null //用来记录最小值
    for(let i=0;i<nums.length;i++){
        let sum = nums[i] //用来保存当前的累加和
        if(sum>=target){ //当前值已经满足条件的了,后面就不用再遍历了
            return 1
        }
        for(let j=i+1;j<nums.length;j++){
            sum+=nums[j]
            if(sum>=target){
                min?min = Math.min(min,j-i+1):min = j-i+1
                break //结束当前的循环
            }
        }
    }
    return min?min:0
};
滑动窗口 最小滑动窗口
var minSubArrayLen = function(target, nums) {
    //滑动窗口 i是窗口的最左侧 j是窗口的最右侧
    let res = null //用来记录最小值
    let sum = 0 //用来记录窗口所有元素的和
    let i = 0, j = 0
    for(j;j<nums.length;j++){
        sum+=nums[j]
        while(sum>=target){
            res?res=Math.min(res,j-i+1):res=j-i+1
            //左侧指针i向右侧移动
            sum-=nums[i++]
        }
    }
    return res?res:0
};

904.水果成篮

暴力解法
var totalFruit = function(fruits) {
    //暴力解法
    let max = 0
    //使用两层循环 外层循环是从下标i开始,j是从i往后开始几个
    for(let i=0;i<fruits.length;i++){
        let type1 = null
        let type2 = null
        type1 = fruits[i]
        let sum = 1//当前篮子中的水果数量
        for(let j=i+1;j<fruits.length;j++){
            if(fruits[j]==type1){
                sum++
            }else if(type2==null){
                type2 = fruits[j]
                sum++
            }else if(fruits[j]==type2){
                sum++
            }else{
                break
            }
        }
        max = Math.max(max,sum)
    }
    return max
};
滑动窗口 这里是最大滑动窗口
var totalFruit = function(fruits) {
    let max = 0//用来记录最大值
    let map = new Map() //用来记录某个种类在滑动窗口中出现的次数,注意窗口中只能由两个键值
    let left = 0 //窗口左侧指针
    //下面right是窗口的右侧指针   只要map中只有两个键值,那么窗口就可以一直扩大直到数组结束
    for(let right=0;right<fruits.length;right++){
        //设置键值
        map.set(fruits[right],map.get(fruits[right])+1||1)
        //只要map对象中的键值个数超过两个,那么左侧指针开始往右侧移动
        while(map.size>2){
            map.set(fruits[left],map.get(fruits[left])-1)
            //一直在删除原来窗口中的键的val值,删除过程中,看那两个键 哪个先删除为0 
            if(map.get(fruits[left])==0){
                map.delete(fruits[left])
            }
            //将某个键值给删除之后进行新的窗口 新的窗口中有一个原先的老的键值还有一个新的键值
            ++left
        }
        max = Math.max(max,right-left+1)
    }
    return max
};

76.最小覆盖子串

在这里插入图片描述

var minWindow = function(s, t) {
    //t中也会有重复的元素,但是t不用去重,因为题目中要求要找的字串中必须和t的字符的数量都是一样的
    let map = new Map() //保存t中的所有的字符 及其数量
    for(let i=0;i<t.length;i++){
        map.set(t.charAt(i),map.get(t.charAt(i))+1||1)
    }

    let left = 0, right = 0
    let minStr = ''
    let size = map.size//保存所需要的字符种类
    for(right;right<s.length;right++){
        if(map.has(s[right])){
            map.set(s[right],map.get(s[right])-1)
        }
        if(map.get(s[right])==0) size-- //需求的字符个数减一
        //只有需求的元素都有了,才会执行while
        while(!size){
            let curStr = s.substring(left,right+1)
            minStr?(minStr =  minStr.length<curStr.length?minStr:curStr):minStr = curStr
            if(map.has(s[left])){
                map.set(s[left],map.get(s[left])+1)
                if(map.get(s[left])==1) size++//需求数量加一
            }
           left++
        }
    }
    return minStr

};

三、螺旋矩阵相关问题

54.螺旋矩阵

讲解参考
在这里插入图片描述
思路:最后判断剩余的情况,只能是一行(从左到右,如果是从下到上,那么必然会有一条边从左到右去连接这条从下到上的边,这就成了逆时针了,显然不符合条件)或者是一列(从上到下,也是同理)

方法一:一圈一圈的push
var spiralOrder = function(matrix) {
    //方法一 :按照圈进行遍历 里外都是矩形圈 由于最大的矩形长或者宽不一样 遍历的最里面最后会剩下一列(从上到下) 或者 一行(从左到右)  res:顺时针遍历的
    if(matrix.length==0) return []
    let top = 0, bottom = matrix.length - 1,left = 0, right = matrix[0].length-1
    let res = [] //记录最终结果
    while(top<bottom&&left<right){
        //遍历上层   由于top<bottom left<right所以每一次的遍历都是有头没有尾巴
        for(let i=left;i<right;i++) res.push(matrix[top][i])
        //遍历右侧
        for(let i=top;i<bottom;i++) res.push(matrix[i][right])
        //遍历下侧
        for(let i=right;i>left;i--) res.push(matrix[bottom][i])
        //遍历左侧
        for(let i=bottom;i>top;i--) res.push(matrix[i][left])
        //遍历完一圈之后,向内进行缩圈
        left++
        right--
        top++
        bottom--
    }
    console.log(res)
    //当while循环不满足条件的时候,没有遍历的只有一行或者一列
    //还剩下一行 从左到右
    //这里要注意:下面的循环只能执行一个 当最后只剩下一个节点的时候 下面的两个条件都满足条件 会重复
    if(top==bottom){
        for(let i=left;i<=right;i++){
            res.push(matrix[top][i])
        }
    }else if(left==right){ //只剩下一列
        for(let i=top;i<=bottom;i++){
            res.push(matrix[i][left])
        }
    }
    return res
};
方法二:螺旋push到底
var spiralOrder = function(matrix) {
    if(matrix.length==0) return []
    let res = []
    let left = 0,top = 0,right = matrix[0].length - 1,bottom = matrix.length - 1
    while(left<=right&&top<=bottom){
        for(let i=left;i<=right;i++) res.push(matrix[top][i])
        top++
        for(let i=top;i<=bottom;i++) res.push(matrix[i][right])
        right--
        if(top>bottom||left>right) break
        //遍历下侧
        for(let i=right;i>=left;i--) res.push(matrix[bottom][i])
        bottom--
        //遍历左侧
        for(let i=bottom;i>=top;i--) res.push(matrix[i][left])
        left++
    }
    return res
};
方法二判断条件的修改
var spiralOrder = function(matrix) {
    if(matrix.length==0) return []
    let res = []
    let left = 0,top = 0,right = matrix[0].length - 1,bottom = matrix.length - 1
    let size = matrix.length*matrix[0].length
    while(res.length!==size){
        for(let i=left;i<=right;i++) res.push(matrix[top][i])
        top++
        for(let i=top;i<=bottom;i++) res.push(matrix[i][right])
        right--
        if(res.length==size) break
        //遍历下侧
        for(let i=right;i>=left;i--) res.push(matrix[bottom][i])
        bottom--
        //遍历左侧
        for(let i=bottom;i>=top;i--) res.push(matrix[i][left])
        left++
    }
    return res
};

59.螺旋矩阵2

在这里插入图片描述

方法一:一圈一圈的加
var generateMatrix = function(n) {
    //题目要求构建一个长宽都是n的矩形
    let top = 0,left = 0,bottom = n-1,right = n-1
    let matrix = new Array(n).fill(0).map(item=>item=new Array(n).fill(0))
    let k = 1
    while(left<right&&top<bottom){
        for(let i=left;i<right;i++) matrix[top][i] = k++
        for(let i=top;i<bottom;i++) matrix[i][right] = k++
        for(let i=right;i>left;i--) matrix[bottom][i] = k++
        for(let i=bottom;i>top;i--) matrix[i][left] = k++
        //向内侧走动
        left++
        right--
        top++
        bottom--
    }
    if(left==right){
        for(let i=top;i<=bottom;i++){
            matrix[i][left] = k++
        }
    }else if(top==bottom){
        for(let i=left;i<=right;i++){
            matrix[top][i] = k++
        }
    }
    return matrix
};
直接一圈到底
var generateMatrix = function(n) {
    //一直加到底
    let matrix = new Array(n).fill(0).map(item=>item = new Array(n).fill(0))
    let top = 0,bottom = n-1,left = 0,right = n - 1
    let k = 1
    while(left<=right&&top<=bottom){
        for(let i=left;i<=right;i++) matrix[top][i] = k++
        top++
        for(let i=top;i<=bottom;i++) matrix[i][right] = k++
        right--
        if(top>bottom||left>right) break
        for(let i=right;i>=left;i--) matrix[bottom][i] = k++
        bottom--
        for(let i=bottom;i>=top;i--) matrix[i][left] = k++
        left++
    }
    return matrix
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值