代码随想录训练营day2

问题一:长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 target 。

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

输入

输出

target = 7, nums = [2,3,1,2,4,3]

2

target = 4, nums = [1,4,4]

1

思路一:暴力

遍历n*i次数组,分别求每个连续子数组的和,如果大于则记录长度,注意是连续子数组,不是子数组。

思路二:前缀和+二分查找

前缀和保留数组前n项元素的和,则有sum[i-1]+s = x ,二分查找寻找x在sum[i]可能出现的位置,只要位置大于等于0,则说明存在记录下标与i之间的差值。

思路三:滑动窗口

右指针不断往前走,直到尽头,同时存储sum,循环判断sum能不能连续消除left指针的元素,如果可以左指针前进,并记录距离,右指针一直前进

代码:

//暴力

func minSubArrayLen(s int, nums []int) int {
    n:= len(nums)
    ans:=math.MaxInt
    for i:=0;i<n;i++{
        res:=0
        for j:=i;j<n;j++{
            res += nums[j]
            if res >= s{
                ans = min(ans,j-i+1)
                break
            }
        }
    }
    if ans == math.MaxInt{
        return 0
    }
    return ans
}

//前缀和
func minSubArrayLen(s int, nums []int) int {
    ans := math.MaxInt32
    n:= len(nums)
    sum:=make([]int,n+1)
    for i:=1;i<= n;i++{
        sum[i] = nums[i-1] + sum[i-1]
    }
    for i:=1;i<=n;i++{
        bigsum := s+ sum[i-1]
        lo := sort.SearchInts(sum,bigsum)
        if lo <=n && lo >0{
            ans = min(ans,lo -i +1)
        }
    }
    if ans == math.MaxInt32 {
        return 0
    }
    return ans

}
//滑动窗口
func minSubArrayLen(s int, nums []int) int {
    n := len(nums)
    if n == 0 { return 0}
    ans := math.MaxInt32
    start, end := 0, 0
    sum := 0
    for end < n {
        sum += nums[end]
        for sum >= s {
            ans = min(ans, end - start + 1)
            sum -= nums[start]
            start++
        }
        end++
    }
    if ans == math.MaxInt32 {return 0}
    return ans
}


func min(x, y int) int {
    if x < y {
        return x
    }
    return y
}

问题二:螺旋矩阵 II

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

输入

输出

n = 3

[[1,2,3],[8,9,4],[7,6,5]]

n = 1

[[1]]

思路:两种思路,归根结底,能把一个圈堵住就行

四矢量法:一共四个循环,每次走一个矢量,奇数个的话,中心堵住一个

转圈法: 转圈法的好处在于不需要处理奇数位

代码:

//四矢量法
func generateMatrix(n int) [][]int {
	arr := make([][]int, n)
	for i := 0; i < n; i++ {
		arr[i] = make([]int, n)
	}
	base_num := 1
	left, right := 0, n-1
	for left <= right {
        for i:=left;i<right;i++{
            arr[left][i] = base_num
            base_num++
        }
        for i:=left;i<right;i++{
            arr[i][right] =base_num
            base_num++
        }
        for i:=right;i>left;i--{
            arr[right][i] =base_num
            base_num++
        }
        for i:= right;i>left;i--{
            arr[i][left]= base_num
            base_num++
        }
		left++
		right--
	}
    mid := n/2
    if n % 2 == 1{
        arr[mid][mid] = base_num;
    }
	return arr
}

//转圈法
func generateMatrix(n int) [][]int {
	arr := make([][]int, n)
	for i := 0; i < n; i++ {
		arr[i] = make([]int, n)
	}
	base_num := 1
	left, right := 0, n-1
	for left <= right {
		//从左到右
		for i := left; i <= right; i++ {
			arr[left][i] = base_num
			base_num++
		}
		//从上到下
		for i := left + 1; i <= right; i++ {
			arr[i][right] = base_num
			base_num++
		}
		//从右往左
		for i := right - 1; i >= left; i-- {
			arr[right][i] = base_num
			base_num++
		}
		//从下往上
		for i := right - 1; i >= left+1; i-- {
			arr[i][left] = base_num
			base_num++
		}
		left++
		right--
	}
	return arr
}

问题三:有序数组的平方

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

输入

输出

nums = [-4,-1,0,3,10]

[0,1,9,16,100]

nums = [-7,-3,2,3,11]

[4,9,9,49,121]

思路一:暴力求,平方,排序

思路很简单,遍历数组,Sort.Int排序

思路二:界限双指针

找到负数与非负数之间的界限,然后进行判断,两者较小的元素,然后进入数组

思路三:相向双指针+倒入结果数组

从两头开始找,如果比较这两值的大小,大的进入数组的最后一个元素,并让数组最后指针前移

代码:

//界限双指针
func sortedSquares(nums []int) []int {
    n := len(nums)
    lastNegIndex := -1
    for i := 0; i < n && nums[i] < 0; i++ {
        lastNegIndex = i
    }

    ans := make([]int, 0, n)
    for i, j := lastNegIndex, lastNegIndex+1; i >= 0 || j < n; {
        if i < 0 {
            ans = append(ans, nums[j]*nums[j])
            j++
        } else if j == n {
            ans = append(ans, nums[i]*nums[i])
            i--
        } else if nums[i]*nums[i] < nums[j]*nums[j] {
            ans = append(ans, nums[i]*nums[i])
            i--
        } else {
            ans = append(ans, nums[j]*nums[j])
            j++
        }
    }

    return ans
}

//相向双指针
func sortedSquares(nums []int) []int {
    n := len(nums)-1
    ans := make([]int, len(nums))
    lf,ri:=0,len(nums)-1

    for lf <= ri{
        x,y := nums[lf]*nums[lf],nums[ri]*nums[ri]

        if x<y{
            ans[n] = y
            ri--
        }else{
            ans[n] = x
            lf++
        }
        n--
    }
    return ans
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吃瓜太狼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值