旋转数组

189. 旋转数组

  • 暴力求解,时间复杂度最大O(N^2)
func rotate(nums []int, k int)  {   
    n := len(nums)
    k = k % n
    if k == 0 {
        return 
    }
    for i:=0;i<k;i++{
        for j:=n-1;j>0;j--{
            nums[j],nums[j-1] = nums[j-1],nums[j]
        } 
    }
    return
}
  • 利用额外数组,空间和时间复杂度都是O(N)
func rotate(nums []int, k int)  {   
    n := len(nums)
    k = k % n
    if k == 0 {
        return 
    }
    tmp := make([]int,n)
    copy(tmp,nums)
    for i:=0;i<n;i++{
        if i < k {
            nums[i] = tmp[n-k+i]
        }else {
            nums[i] = tmp[i-k]
        }
    }
    return
}
  • 旋转,没有额外空间,时间复杂度O(N)
func rotate(nums []int, k int)  {   
    n := len(nums)
    k = k % n
    if k == 0 {
        return 
    }
    // 整个旋转,在分别旋转前k个和后面n-k个
    reverse(nums)
    reverse(nums[:k])
    reverse(nums[k:])
    return
}

func reverse(nums []int){
    n := len(nums)
    for i :=0;i<n/2;i++{
        nums[i],nums[n-1-i] = nums[n-1-i],nums[i]
    }
}

153. 寻找旋转排序数组中的最小值

解法1,遍历,时间复杂度O(N)

func findMin(nums []int) int {
    n := len(nums)
    if n == 0 {
        return 0
    }
    for i:=1;i<n;i++{
        if nums[i] < nums[i-1]{
            return nums[i]
        }
    }    
    return nums[0]
}

解法2,二分查找,时间复杂度O(log(N))

func findMin(nums []int) int {
    n := len(nums)
    if n == 0 {
        return 0
    }
    l,r := 0,n-1
    // 没有旋转
    if nums[l] < nums[r] {
        return nums[l]
    }

    // 对于旋转过的,如果中间大于左边,比如2,3,4,5,6,1。去中间的右边查找
    // 如果中间小于左边,去中间的6,1,2,3,4,5,去中间的左边找
    for l < r {
        mid := l + (r-l)/2
        // 终止条件
        if mid > 0 && nums[mid] < nums[mid-1] {
            return nums[mid]
        }else if mid + 1 < n && nums[mid] > nums[mid+1]{
            return nums[mid+1]
        }
        if nums[mid]>nums[l]{
            l = mid
        }else {
            r = mid
        }
    }
    return nums[l]
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值