LeetCode每日一題(二)

LeetCode每日一題(二)

面試題53 - I. 在排序數組中查找數字 I

統計一個數字在排序數組中出現的次數。

示例 1:

輸入: nums = [5,7,7,8,8,10], target = 8
輸出: 2

示例 2:

輸入: nums = [5,7,7,8,8,10], target = 6
輸出: 0

限制:

0 <= 數組長度 <= 50000

題目中出現了排序,那我們首要選擇二分法查找

二分法的通用寫法:

// nums爲數組,target爲目標值
int left = 0;
int right = nums.length-1;
while(left <= right){
  	//這裏有兩種寫法
  	//第一種,int mid = (right - left)/2;
  	//第二種,int mid = left + (right-left)/2 ,因爲我們的數組可能會很大,導致left+right會超過int型的最大值2147483647,我們選擇使用 int mid = left + (right-left)/2 
		int mid = left + (right-left)/2if(nums[mid] == target){
      // 找到目標值
    }else if(nums[mid] < target){
      // 中間值小於目標值,證明需要尋找的目標值的區間一定在 mid+1 ~ right這個區間裏
      left = mid+1;
    }else if(nums[mid] > target){
      //中間值大於目標值,證明需要尋找的值得區間一定是 left ~ mid-1 這個區間裏
      right = mid-1;
    }
}

​ 我們回過頭來看這道題,提供的數組nums裏可能會有重複值,但是這個數組是個排序數組,我們依然可以使用二分法查找

public int search(int[] nums, int target) {
  	// nums爲數組,target爲目標值
    if (nums.length == 0) return 0;
    int res = 0;
    int left = 0;
    int right = nums.length - 1;
    while (left <= right) {
    		//這裏有兩種寫法
  			//第一種,int mid = (right - left)/2;
  			//第二種,int mid = left + (right-left)/2 ,因爲我們的數組可能會很大,導致left+right會超過int型的最大值2147483647,我們選擇使用 int mid = left + (right-left)/2 
        int mid = left + (right - left) / 2;
        if (nums[mid] > target) {
          	// 中間值小於目標值,證明需要尋找的目標值的區間一定在 mid+1 ~ right這個區間裏
            right = mid - 1;
        } else if (nums[mid] < target) {
            // 中間值小於目標值,證明需要尋找的目標值的區間一定在 mid+1 ~ right這個區間裏
            left = mid + 1;
        } else if (nums[mid] == target) {
            res++;
            int tempLeft = mid;
            while (tempLeft-- > 0 && nums[tempLeft] == target) {
                res++;
            }
            int tempRight = mid;
            while (tempRight++ < nums.length - 1 && nums[tempRight] == target) {
                res++;
            }
            return res;
         }
    }
}

前面幾個判斷都和通用的一樣,只有我們找到目標值這裏有一些變化,單獨拿出來看一下

		else if (nums[mid] == target) {
        res++;
        int tempLeft = mid;
        while (tempLeft-- > 0 && nums[tempLeft] == target) {
            res++;
        }
        int tempRight = mid;
        while (tempRight++ < nums.length - 1 && nums[tempRight] == target) {
            res++;
        }
        return res;
     }
  1. 首先,我們找到了目標值,但是目標值在數組裏可能不是一個,可能會有多個,但是,這幾個相同的數一定的相鄰的,畢竟是排序數組嘛,所以,我們從mid這個位置向前,向後尋找和nums[mid]相同的值,就可以把所有出現的個數都找到了。
  2. 向前尋找,對比mid和mid-1,如果不相等,證明mid的左邊沒有和taget相等的數,如果相等,結果+1,mid-1,繼續循環,要注意邊界,如果mid==0,那mid-1就會超出邊界。
  3. 向後尋找,對比mid和mid+1,如果不相等,證明mid的右邊沒有和taget相等的數,如果相等,結果+1,mid+1,繼續循環,同樣也要注意邊界,mid+1要小於等於nums.length -1
  4. 循環結束,直接return
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章