1. 程式人生 > >頭條面試題-統計有序數組裡平方和的數目

頭條面試題-統計有序數組裡平方和的數目

給你一個有序整數陣列,陣列中的數可以是正數、負數、零,請實現一個函式,這個函式返回一個整數:返回這個陣列所有數的平方值中有多少種不同的取值。舉例:

  1. nums = {-1,1,1,1},

    那麼你應該返回的是:1。因為這個陣列所有數的平方取值都是1,只有一種取值

  2. nums = {-1,0,1,2,3}

    你應該返回4,因為nums陣列所有元素的平方值一共4種取值:1,0,4,9

在往下看之前,請先進行思考,如果當時是你在面試,你會給出什麼樣的結題思路?下面會給出兩種解法,最優解:時間複雜度:O(n)、空間複雜度O(1)。無論有沒有思路,在往下看之前一定要有自己的思考

分析:

方法一:暴力法,先算平方和,儲存在一個數組中,然後使用集合統計不同。

方法二:集合儲存平方和。直接先遍歷一次得到平方和,將平方和放入集合中,輸出集合的大小。時間複雜度為O(n),空間複雜度為O(n).

方法三:以上兩種方法都沒有使用到陣列有序,需要計算的是不同的平方和,那麼平方和相同時有兩種情況,一:兩個元素是相鄰元素,元素值本身相同;二:兩個元素絕對值相等;對於第一種情況可以直接比較是否與相鄰元素相等,相等時不計數;對於第二種情況利用陣列有序的條件,使用雙指標分別指向陣列的頭和尾,相等時不計數。兩指標向中間移動。

public static int DifferentMi(int nums[]){
        int cnt=0;
        int i=0,j=nums.length-1;
        while(i<j){
            while(i<j && nums[i]*nums[i]==nums[j]*nums[j])
                i++;
            if(nums[i]*nums[i]>nums[j]*nums[j]){
                while(i<j && nums[i]*nums[i]==nums[i+1]*nums[i+1])
                    i++;
                i++;
            }else{
                while(i<j && nums[j]*nums[j]==nums[j-1]*nums[j-1])
                    j--;
                j--;
            }
            cnt++;
        }
        return cnt;
    }