递增数组找和x值最接近值的第一个下标
算法题:递增数组找和x值最接近值的下标
说明:
- 最接近指差的绝对值最小
- 元素可重复
- 相同接近时取最小下标
- 时间复杂度要求O(logn)
例子:
1, 2, 2, 3, 5, 6, 6, 9, 19
x: 4 index: 3
x: 8 index: 7
x: 2 index: 1
x: 7 index: 5
x: 0 index: 0
x: 100 index: 8
方法一:
public class Main { public static void main(String[] args) { int[] arr={1,2,2,3,5,6,6,9,19}; int[] res={4,8,2,7,0,100}; int index; for(int x:res){ index=find(arr, x); System.out.println("index:"+index); } } private static int find(int[] arr, int target){ int n=arr.length; if(target<=arr[0]) return 0; if(target>arr[n-1]) return n-1; int low=0, high=n-1; int mid=0; while(low<high){ mid=low+(high-low)/2; if(arr[mid]>=target){ if(mid>0&&arr[mid-1]<target){ high=Math.abs(target-arr[mid-1])<=Math.abs(target-arr[mid])?mid-1:mid; continue; } high=mid; }else{ //目标值比中间值大 if(mid<n-1&&arr[mid+1]>target){ low=Math.abs(target-arr[mid])<=Math.abs(target-arr[mid+1])?mid:mid+1; continue; } low=mid+1; } } while(low>0&&arr[low]==arr[low-1]) low--; return low; } }
方法二:把目标值的值改成数组中最接近它的值,可以取到最左边的下标,时间复杂度严格为O(logn)
public class Main { public static void main(String[] args) { int[] arr={1,2,2,3,5,6,6,9,19}; int[] res={4,8,2,7,0,100}; int index; for(int x: res){ index=find(arr, x); System.out.println("index:"+index); } } private static int find(int[] arr, int target){ int n=arr.length; if(target<=arr[0]) return 0; int temp=target; int low=0, high=n-1; int mid=0; while(low<high){ mid=low+(high-low)/2; if(arr[mid]==temp){ high=mid; }else if(arr[mid]>temp){ if(mid>0&&arr[mid-1]<temp){ if((temp-arr[mid-1])>(arr[mid]-temp)) return mid; else temp=arr[mid-1]; //改变目标值的值,取最左边的下标 } else if(mid>0&&arr[mid-1]>=temp) high=mid-1; }else{ //目标值比中间值大 if(mid<n-1&&arr[mid+1]>temp){ if((temp-arr[mid])>(arr[mid+1]-temp)) return mid+1; else temp=arr[mid]; //改变目标值的值,取最左边的下标 } else if(mid<n-1&&arr[mid+1]<=temp) low=mid+1; } } return low; } }

浙公网安备 33010602011771号