[Leetcode]Find Minimum in Rotated Sorted Array I & II

本文介绍了一种在已知和未知旋转点的有序数组中寻找最小元素的方法,提供了两种复杂度分别为O(n)和O(log n)的算法实现,并讨论了数组中存在重复元素时的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Suppose a sorted array is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

Find the minimum element.

You may assume no duplicate exists in the array.


在一个被翻转的有序数组中找到最小元素。考虑没有重复元素的情况:

O(n)

class Solution {
public:
    int findMin(vector<int> &num) {
        int head = 0,end = num.size()-1;
        if(num[end]<num[head]){
            while(num[end]>num[end-1]&&end>0){
                end--;
            }
            return num[end];
        }
        else{
            return num[head];
        }
    }
};

O(lgn)

因为数组被分成前后两部分,并且前半部分的数值总比后半部分大。使用二叉查找法,看mid位置的值,如果比数组最后一个元素还大,那这个置肯定位于大数部分,反之则位于小数部分。这样步步逼近,就可以找到最小值。

class Solution{
public:
	int findMin(vector<int> &num){
        return find(num,0,num.size()-1);
	}
	int find(vector<int> num, int left, int right){
		if (num[left] <= num[right]) return num[left];
		int mid = (left + right) >> 1;
		if (num[mid] > num[right])
			return find(num, mid + 1, right);
		else
			return find(num,left,mid);
	}
};

Follow up for "Find Minimum in Rotated Sorted Array":
What if duplicates are allowed?

Would this affect the run-time complexity? How and why?

Suppose a sorted array is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

Find the minimum element.

The array may contain duplicates.

现在考虑第二题,有重复元素出现的情况。如果有重复元素出现,那么翻转处有可能位于重复元素的范围内,如果这样的话则需要将前后两端的重复元素去掉,将左右两个游标分别++和--。这里有一点需要特别注意的是,当右侧游标--时,right元素一定要比right-1元素要大,否则就不能--。如果数组中剩下的全部是重复元素,则返回重复元素。剩下的操作和第一题一样。

class Solution {
public:
	int findMin(vector<int> &num) {
		return find(num, 0, num.size() - 1);
	}
	int find(vector<int> num, int left, int right){
		while (left < right && num[left] == num[right]&&num[right-1] <= num[right]){
			left++;
			right--;
		}
		if (left >= right){
			return num[left];
		}
		if (num[left] < num[right]) return num[left];
		int mid = (left + right) >> 1;
		if (num[mid] > num[right])
			return find(num, mid + 1, right);
		else
			return find(num, left, mid);
	}
};




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值