1. 程式人生 > >劍指Offer-題53(二)(Java版):0到n-1中缺失的數字

劍指Offer-題53(二)(Java版):0到n-1中缺失的數字

參考自:《劍指Offer——名企面試官精講典型程式設計題》

題目:0到n-1中缺失的數字
一個長度為n-1的遞增排序陣列中的所有數字都是唯一的,並且每個數字都在範圍0到n-1之內。在範圍0到n-1的n個數字中有且只有一個數字不在該陣列中,請找出這個數字。

主要思路:若陣列沒有缺失,則每個數字和它的下標都相等。然而,現在陣列有缺失,說明從缺失的那個數開始,後面的數字都比它的下標大1。因此找出第一個數值和下標不相等的數,那麼,它的下標就是缺失的那個數。
  陣列可看成兩部分,前半段數值和下標相等,後半段數值和下標不相等,且陣列是有序的。所以,使用二分查詢,若中間數的值和下標相等,則在後半段繼續尋找;若中間數的值和下標不相等,且中間數的前一個元素的值等於它的下標相等,那麼這個中間數就是第一個值和下標不相等的數,它的下標就是缺失的那個數,否則繼續在前半段尋找。

關鍵點:二分查詢,數值和下標的關係

時間複雜度:O(logn)

public class MissingNumber
{
    public static void main(String[] args)
    {
        System.out.println(findMissingNumber(new int[]{0, 1, 2, 3, 4})); //5
        System.out.println(findMissingNumber(new int[]{1, 2, 3, 4})); //0
        System.out.println(findMissingNumber(new
int[]{0, 1, 2, 4, 5})); //3 } private static int findMissingNumber(int[] data) { if (data == null || data.length <= 0) return -1; int left = 0; int right = data.length - 1; //值和下標相等的數在陣列前半段 //值和下標不相等的數在陣列後半段 while (left <= right) { int
middle = left + (right - left) / 2; //值和下標不相等 if (data[middle] != middle) { //找到缺失的數 if (middle == 0 || data[middle - 1] == middle - 1) { return middle; } else { right = middle - 1; //中間值和下標不相等,則需在前半段查詢 } } else left = middle + 1; //中間值和下標相等,則需在後半段查詢 } //陣列前面的數都和下標相等,說明缺失的是最大的那個數 if (left == data.length) return data.length; return -1; } }