leetcode做题笔记33

整数数组 nums 按升序排列,数组中的值 互不相同 。

在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。

给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。

你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。

目录

思路一:循环(时间超限)

思路二:二分法

做题历程:

反省:

问题:

收获:

总结:


思路一:循环(时间超限)

虽然减小了所要循环的数的规模,但时间复杂度还是没达到要求

int search(int* nums, int numsSize, int target){
    if(target>nums[0])
    {
        int i = 1;
        while(nums[i]<nums[i+1])
        {
            for(;i<numsSize/2;i++)
            {
                if(target==nums[i])return i;
            }
             i += i/2;
        }
        
        return -1;
    }
    else if(target<nums[0])
    {
        int i = numsSize-1;
        while(nums[i]>nums[i-1])
        {
           for(;i>numsSize/2;i--)
            {
                if(target == nums[i])return i;
            }
            i -= i/2; 
        }
        return -1;
    }
    else return 0;
}

时间复杂度O(n),空间复杂度O(1)

思路二:二分法

利用两个指针不断缩小范围,使时间复杂度达到O(logn)

int search(int* nums, int numsSize, int target){
    int low = 0, high = numsSize - 1;
    while(low <= high){
        int mid=(high - low) / 2 + low; 
        if(nums[mid] == target){ 
            return mid;
        }
        if(nums[low] <= nums[mid]){    
            if(target >= nums[low] && target <nums[mid])
                high = mid - 1;
            else                                 
                low = mid + 1;
        }
        else{                       
            if(target > nums[mid] && target <= nums[high])
                low = mid + 1;                   
            else
                high = mid - 1;
        }
    }
    return -1;
}

时间复杂度O(logn),空间复杂度O(1)

做题历程:

一开始想到因为旋转了数组,可以通过判断目标数与第一个数的大小来决定是从前往后还是从后往前循环看是否相等,同时让比较的区域通过看该位置前一个与后一个比较来判断是否已到选择数的位置来决定返回-1,该方法虽然可行但是时间复杂度上还是有所欠缺,为O(n),提交时时间超过限制,之后想到使用二分法,将数组两边用指针来不断缩小范围进行查找,将时间复杂度缩小到了O(logn)

反省:

问题:

时间复杂度没有降低到O(logn)

收获:

对二分法的应用更加熟练,对于是否需更改边界的条件更加明确

总结:

该题主要考察了二分法的应用,对于时间复杂度要求较高的问题,可尝试二分法来降低时间复杂度

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值