有序数组arr可能经过一次旋转处理,也可能没有,且arr可能存在重复的数。例如,有序数组[1, 2, 3, 4, 5, 6, 7],可以旋转处理成[4, 5, 6, 7, 1, 2, 3]等。给定一个可能旋转过的有序数组arr,再给定一个数num,返回arr中是否含有num
关于旋转操作:可以简单的理解为把序列从某个位置切成两段然后交换位置
[要求]
期望复杂度为
第一行两个整数N, num。分别表示数组大小, 需要找的数。
接下来一行N个整数表示数组内的数。
若num存在于数组中,输出"Yes",否则输出"No"
7 7 4 5 6 7 1 2 3
Yes
7 998244353 4 5 6 7 1 2 3
No
#include<iostream>
#include<vector>
using namespace std;
bool search(vector<int>& nums, int target) {
int left = 0, right = nums.size() - 1;
while( left <= right )
{
int mid = left + ( right - left ) / 2;
if( target == nums[mid] )
return true;
if( target == nums[left] )
return true;
if( target == nums[right] )
return true;
// nums[left]、nums[mid]和nums[right]三者相等
if( nums[left] == nums[mid] && nums[mid] == nums[right] )
{
left++;
right--;
}
else if( nums[left] <= nums[mid] ) // 如果前半段有序
{
if( nums[left] < target && target < nums[mid] )
right = mid - 1;
else
left = mid + 1;
}
else // 否则后半段有序
{
if( nums[mid] < target && target < nums[right] )
left = mid + 1;
else
right = mid - 1;
}
}
return false;
}
int main(){
int N, num;
cin >> N >> num;
vector<int> arr(N, 0);
for(int i = 0; i < N; i++){
cin >> arr[i];
}
if(search(arr,num)) cout << "Yes";
else cout << "No";
return 0;
} import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(), target = sc.nextInt();
int[] arr = new int[n];
for(int i = 0; i < n; i++)
arr[i] = sc.nextInt();
int left = 0, right = n - 1;
while(left < right) {
int mid = left + (right - left) / 2;
if(target == arr[mid] || target == arr[left] || target == arr[right]){
System.out.println("Yes"); // 找到目标,输出Yes
return;
}
if(arr[mid] <= arr[right]){ // 右边有序
if(target > arr[mid] && target < arr[right])
left = mid + 1; // 且目标在这个区间当中
else
right = mid - 1;
}else{
if(arr[left] < target && arr[mid] > target)
right = mid - 1; //目标在左边
else
left = mid + 1; // 目标在右边
}
}
System.out.println("No");
}
} import java.util.*;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scan=new Scanner(System.in);
while(scan.hasNext())
{
int n=scan.nextInt();
int target=scan.nextInt();
int[]arr=new int[n];
for(int i=0;i<n;i++)
{
arr[i]=scan.nextInt();
}
boolean flag=isInarr(arr,target);
if(flag)
System.out.println("Yes");
else
System.out.println("No");
}
}
public static boolean isInarr(int[] arr, int key){
if(arr.length == 0){
return false;
}
int left = 0;
int right = arr.length - 1;
while (left < right){
int mid = left + (right - left)/2;
if (arr[mid] == key){
return true;
}
//如果前半段有序
if (arr[mid] > arr[left]){
//判断Key是否在前半段,如果在,则继续遍历前半段;如果不在,则遍历后半段
if (arr[mid] > key){
right = mid - 1;
}else {
left = mid + 1;
}
}
//如果后半段有序
if (arr[mid] < arr[right]){
//判断Key是否在后半段,如果在,则继续遍历后半段;如果不在,则遍历前半段
if (arr[mid] < key){
left = mid + 1;
}else {
right = mid - 1;
}
}
}
return false;
}
} import java.util.Scanner;
import java.util.Arrays;
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int num=sc.nextInt();
int[] arr=new int[n];
for(int i=0;i<n;i++){
arr[i]=sc.nextInt();
}
Arrays.sort(arr);
System.out.print(isInside(arr,n,num)?"Yes":"No");
}
private static boolean isInside(int[] arr, int n, int num) {
int left = 0;
int right = n - 1;
while (left < right) {
int mid = (left + right) / 2;
if (arr[mid] == num) {
return true;
}
if (arr[mid] < arr[right]) {
if (arr[mid] > num || arr[right] < num) {
right = mid - 1;
} else if (arr[right] == num){
return true;
} else {
left = mid + 1;
}
} else if (arr[mid] > arr[right]){
if (arr[mid] < num || arr[left] > num) {
left = mid + 1;
} else if (arr[left] == num) {
return true;
} else {
right = mid - 1;
}
} else {
right--;
}
}
return false;
}
}
#include <cstdio>
using namespace std;
const int N = 100000;
int n, k;
int a[N];
int main(void) {
scanf("%d%d", &n, &k);
for ( int i = 0; i <n; ++i )
scanf("%d", a + i);
--n;
while ( n > 0 && a[n] == a[0] ) --n;
if ( a[0] == a[n] ) {
puts( a[0] == k ? "Yes" : "No");
return 0;
}
int l = 0, r = n, m;
bool flag = false;
while ( l < r ) {
m = l + r >> 1;
if ( a[m] == k ) {
flag = true;
break;
}
if ( a[m] >= a[0] ) {
if ( a[l] <= k && k <= a[m] ) r = m;
else l = m + 1;
} else {
if ( k <= a[m] ) r = m;
else l = m + 1;
}
}
puts( flag ? "Yes" : "No");
return 0;
} 上面的代码漏了个条件。。。 #include <cstdio>
using namespace std;
const int N = 100000;
int n, k;
int a[N];
int main(void) {
scanf("%d%d", &n, &k);
for ( int i = 0; i <n; ++i )
scanf("%d", a + i);
--n;
while ( n > 0 && a[n] == a[0] ) --n;
if ( a[0] == a[n] ) {
puts( a[0] == k ? "Yes" : "No");
return 0;
}
int l = 0, r = n, m;
while ( l < r ) {
m = l + r >> 1;
if ( a[m] == k ) {
puts("Yes");
return 0;
}
if ( a[m] >= a[0] ) {
if ( a[l] <= k && k <= a[m] ) r = m;
else l = m + 1;
} else {
if ( k <= a[m] || k > a[n]) r = m;
else l = m + 1;
}
}
puts( a[r] == k ? "Yes" : "No");
return 0;
}