1. 程式人生 > 其它 >leetcode 精選top面試題 - 38. 外觀數列

leetcode 精選top面試題 - 38. 外觀數列

技術標籤:Java資料結構Java資料結構插值查詢java

一、插值查詢演算法基本思想

插值查詢是一種在有序陣列(前提條件)中查詢某一特定元素的查詢演算法。插值查詢基於二分查詢**,不同的是插值查詢每次從自適應mid處開始查詢**,提高查詢效率。

二分查詢查詢點和插值查詢查詢點計算如下:
在這裡插入圖片描述
其中key為待查詢元素,low為待查詢區間左端,high為待查詢區間右端,mid為自適應查詢點
插值查詢將上述的比例引數1/2改進為自適應,根據待查詢元素在整個有序陣列中所處的位置,使mid值的變化更靠近待查詢元素key,可以間接地減少了比較次數。

二、程式碼實現

1、遞迴方式

package Search;
import java.util.Arrays; import java.util.Scanner; public class InsertValueSearch { public static int insertvaluesearch(int arr[],int value,int low,int high) { while(low<=high) { int mid=low+(high-low)*(value-arr[low])/(arr[high]-arr[low]);//插值查詢中間索引公式 if(arr[mid]==value) {//若中間位置值等於我們所需要查詢值,即返回中間值
return mid; } if(arr[mid]<value) {//若中間位置值小於我們所需查詢值,則向右遞迴且將下界值變為mid+1 return insertvaluesearch(arr,value,mid+1,high); } if(arr[mid]>value) {//若中間位置值大於我們所需查詢值,則向左遞迴將上界值變為mid-1 return insertvaluesearch(arr,value,low,mid-1); } } return -1; } public static void main(
String[] args) { int[] arr= {31,17,5,47,11,33,3,19,13,59,1,43,41,37,7,53,29}; Arrays.sort(arr);//採用插值查詢時,需要對該陣列進行排序 Scanner sc=new Scanner(System.in); System.out.println("請輸入查詢元素:"); int value=sc.nextInt(); System.out.printf("查詢元素 %d 的位置是 %d ",value,insertvaluesearch(arr,value,0,arr.length-1)); } }

執行結果:

請輸入查詢元素:
37
查詢元素 37 的位置是 11

2、非遞迴方式

package Search;

import java.util.Arrays;
import java.util.Scanner;

public class InsertValueSearch {
	public static int insertvaluesearch(int arr[],int value) {
		int low=0;//指標low表示待查元素所在範圍的下界,下界索引從0開始
		int high=arr.length-1;//指標high表示待查元素所在範圍的上界
		while(low<=high) {
			int mid=low+(high-low)*(value-arr[low])/(arr[high]-arr[low]);//插值查詢中間索引公式
			if(arr[mid]==value) {//若中間位置值等於我們所需要查詢值,即返回中間值
				return mid;
			}
			if(arr[mid]<value) {//若中間位置值小於我們所需查詢值,則向右遞迴且將下界值變為mid+1
				low=mid+1;
			}
			if(arr[mid]>value) {//若中間位置值大於我們所需查詢值,則向左遞迴將上界值變為mid-1
				high=mid-1;
			}
		}
		return -1;
	}
	public static void main(String[] args) {
		int[] arr= {31,17,5,47,11,33,3,19,13,59,1,43,41,37,7,53,29};
		Arrays.sort(arr);//採用插值查詢時,需要對該陣列進行排序
		Scanner sc=new Scanner(System.in);
		System.out.println("請輸入查詢元素:");
		int value=sc.nextInt();
		System.out.printf("查詢元素 %d 的位置是 %d ",value,insertvaluesearch(arr,value));
	}
}

執行結果:

請輸入查詢元素:
43
查詢元素 43 的位置是 13 

三、插值查詢演算法的注意事項

(1)對於資料量較大,關鍵字分佈比較均勻的查詢表來說,採用插值查詢時速度較快。
(2)在關鍵字分佈不均勻的情況下,插值查詢不一定比折半查詢好