可查找重復元素的二分查找算法


可查找重復元素的二分查找算法

二分查找算法思想:又稱為 折半查找,二分查找適合對已經排序好的數據集合進行查找。假設有一升序的數據集合,先找出升序集合中最中間的元素,將數據集合划分為兩個子集,將最中間的元素和關鍵字key進行比較,如果等於key則返回;如果大於關鍵字key,則在前一個數據集合中查找;否則在后一個子集中查找,直到找到為止;如果沒找到則返回-1。

思路:

1、先定義兩個下標 , left = 0 , right = arr.length -1;

2、因為我們也不知道要循環多少次,定義一個while循環,終止條件為right>left

3、因為是二分查找,定義一個mid = left + (right - left)/2; //;防止數據過大溢出

4、定義三個if語句,如果 target == arr[mid], return mid;這是經典的二分查找,我們需要在這做改進

4.1、改進經典二分算法,二分查找是基於有序的數組,重復的元素都在一起。我們只需要在if(target == arr[mid])里面修改即可;我們需要返回第一個出現target的下標;因為我們也不知道mid前面有幾個重復的元素因此我們需要一個while(mid>=0)的循環,mid--,然后比對arr[mid]和target,只要不一樣就終止,返回

5、如果 target < arr[mid] , right = mid - 1;

6、如果target > arr[mid] , left = mid + 1;

知道了思路,我們來編程實現一下吧

/**
	 * 可查找重復元素的二分查找算法
	 * 思路:	
	 * 	1、先定義兩個下標 , left = 0 , right = arr.length -1;
	 * 	2、因為我們也不知道要循環多少次,定義一個while循環,終止條件為right>left
	 * 	3、因為是二分查找,定義一個mid = left + (right - left) / 2;防止數據過大溢出
	 * 	4、定義三個if語句,如果 target == arr[mid], return mid;這是經典的二分查找,我們需要在這做改進
	 * 	4.1、改進經典二分算法,因為可能有重復元素,我們需要返回第一個出現target的下標;因為我們也不知道mid前面有幾個重復的元素
	 * 因此我們需要一個while(mid>=0)的循環,mid--,然后比對arr[mid]和target,只要不一樣就終止,返回
	 * 	5、如果 target < arr[mid] , right = mid - 1;
	 * 	6、如果target > arr[mid] , left = mid + 1;
	 * @param nums
	 * @param target
	 * @return
	 */
	public static int binarySearch(int[] nums , int target){
		
		int left = 0;
		int right = nums.length - 1;
		
		while(left <= right ) {
			int mid = (left + (right - left) / 2);
			if( target == nums[mid] ) {
				while(mid >= 0) {
					if(nums[mid] != target) {
						break;
					}
					mid--;
				}
				if(mid <= -1 ) {
					return 0;
				}
				return mid + 1;//多減了一次,返回的時候需要再加1
			}else if( target < nums[mid] ) {
				right = mid - 1;
			}else {
				left = mid + 1;
			}
		}
		
		return -1;
	}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM