代码随想录day2|977.有序数组的平方|209.长度最小的子数组|59.螺旋矩阵II|Golang

目录

 

977.有序数组的平方 (golang)

        给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

思路1:暴力遍历:

        遍历整个nums,每个nums[i] = nums[i]*nums[i]。然后排序一下。就是每个数平方之后,排个序。

func sortedSquares(nums []int) []int {
    for i:=0;i<len(nums);i++{
        nums[i] = nums[i]*nums[i]   //数值的值变为其平方后的值
    }
    sort.Ints(nums) //对数组排序
    return nums
}

//这个时间复杂度是 O(n + nlogn), 可以说是O(nlogn)的时间复杂度

思路2:双指针

        双指针就是一个在前一个在后。

        因为数组其实是有序的, 只不过负数平方之后可能成为最大数了。那么数组平方的最大值就在数组的两端,不是最左边就是最右边,不可能是中间。

        此时可以考虑双指针法了,left指向起始位置,right指向终止位置(最后的下标)。

left, right := 0, len(nums)-1

定义一个新数组result,和nums数组一样的大小,让k指向result数组终止位置(最后的下标)。

result := make([]int,len(nums))
k := len(nums)-1

接下来就是比较。比较双指针的大小,也就是比较left下标所对应值的平方和right下标所对应值的平方大小。大的那一个放在result[k]里面。每次放完后k都要--。

定义一个新数组result,和nums数组一样的大小,让k指向result数组终止位置。

        如果nums[left] * nums[left] > nums[right] * nums[right]

                那么result[k] = nums[left] * nums[left];

                k--

        如果nums[i] * nums[i]

                那么result[k] = nums[right] * nums[right]

                k--

func sortedSquares(nums []int) []int {
    left, right := 0, len(nums)-1
    k := len(nums)-1
    result := make([]int,len(nums))
    for left <= right {    //要小于等于,相等的时候也要取平方然后放进result得啊
        if nums[left]*nums[left] > nums[right]*nums[right] {    
            result[k] = nums[left]*nums[left]    //选择大的
            k--    //别忘记每次第k个位置填完之后要--
            left++    //从左往右移动
        } else {
            result[k] = nums[right]*nums[right]    //选择大的
            k--
            right--    //从右往左移
        }
    }
    return result    //返回新的数组
}

209、长度最小的子数组(golang)

        给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

分析:暴力解法

        本题go用暴力会超时

func minSubArrayLen(target int, nums []int) int {
    count := len(nums)+1
    for i:=0;i<len(nums);i++{
        sum := 0 
        for j:=i;j<len(nums);j++{
            sum += nums[j]
            if sum >= target {
                count = min(count, j-i+1)
                break
            }   
        }
    }

    if count == len(nums)+1 {
        return 0
    }
    return count
}
func min(a , b int) int {
    if a > b {
        return b
    }
    return a 
}

分析:滑动窗口​

        所谓滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。

        在暴力解法中,是一个for循环滑动窗口的起始位置,一个for循环为滑动窗口的终止位置,用两个for循环 完成了一个不断搜索区间的过程。

在本题中实现滑动窗口,主要确定如下三点:

  • 窗口内是什么?
  • 如何移动窗口的起始位置?
  • 如何移动窗口的结束位置?

窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。

窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了(也就是该缩小了)。

窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。

go代码如下

func minSubArrayLen(target int, nums []int) int {
    left, right := 0,0    //
    sum := 0
    res := len(nums)+1
    for right < len(nums) {    
        sum += nums[right]     // 窗口内。
        for sum >= target {    //移动窗口起始位置,注意是for不是if。因为可能sum的总和减去左边一次之后还是大于target的,还需要再继续缩短区间啊
            res = min(res, right-left+1)    //记录当前满足条件的子数组
            sum -= nums[left]    //你往右移动,左边的就要删掉了。
            left++    //往右移动
        }
        right++    //正常往右移动
    }


  if res == len(nums)+1 {    //如果res 没变过,也就是不存在符合条件的子数组

    return 0
  }

  
  return res    //返回符合条件的子数组长度
}

func min(a, b int) int {
  if a > b {
    return b
  } 
  return a
}

59.螺旋矩阵II

        给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。

示例:

输入: 3

输出:

[[ 1, 2, 3 ],

 [ 8, 9, 4 ],

 [ 7, 6, 5 ] ]

思路:

这一道题主要是模拟。模拟顺时针画矩阵的过程:

  • 填充上行从左到右
  • 填充右列从上到下
  • 填充下行从右到左
  • 填充左列从下到上

由外向内一圈一圈这么画下去。

func generateMatrix(n int) [][]int {
  //边长与填充数字
    top,bottom,left,right := 0,n-1,0,n-1
    num := 1
  
  //初始化矩阵
    matrix := make([][]int,n)
    for i, _ := range matrix {
        matrix[i] = make([]int,n)        
    }
    tar := n * n
    
  //开始依次填充
  for num <= tar {
      for i:=left;i<=right;i++{
          matrix[top][i] = num     //填充都是某一行的第i列。所以i是列,变的是列
          num++
      }
      top++    //填充完一次top就往下移

      for i:=top;i<=bottom;i++{
          matrix[i][right] = num    //填充的都是某一列的第i行,所以i是行,变的是行
          num++
      }
      right--    //填完一次right就往左边移

      for i:=right;i>=left;i--{
          matrix[bottom][i] = num    //填充的都是某一行的第i列,所以i是列,变的是列
          num++
      }
      bottom--    //填完一次bottom就往上移

      for i:=bottom;i>=top;i--{
          matrix[i][left] = num    //填充的都是某一列的的第i行,所以i是行,变得是行
          num++
      }
      left++    //填完一次left就往右移动
  }
    return matrix
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值