1. 程式人生 > 其它 >LeetCode刷題之陣列篇day2

LeetCode刷題之陣列篇day2

技術標籤:javaleetcode

面試題 17.10. 主要元素

陣列中佔比超過一半的元素稱之為主要元素。給定一個整數陣列,找到它的主要元素。若沒有,返回-1。
你有辦法在時間複雜度為 O(N),空間複雜度為 O(1) 內完成嗎?

第一次提交

class Solution {
    public int majorityElement(int[] nums) {
        int count = nums.length;
        if (nums == null)
            return -1;
        if (count == 1)
            return nums[0];
        int maxelem=-1,maxcount=0;
        for (int i = 0;i<count;i++){
            int elem = nums[i];
            int c=0;
            for(int j = 0;j<count;j++){
                if(nums[j]==elem)
                    c++;
            }
            if(c>maxcount){
                maxcount = c;
                maxelem = elem;
            }
        }
        if(maxcount>count/2)
            return maxelem;
        else
            return -1;
    }
}

TLE。暴力求解,時間複雜度達到了O(n2)。

第二次提交

class Solution {
    public int majorityElement(int[] nums) {
        int n = nums.length;
        if (nums == null)
            return -1;
        if (n == 1)
            return nums[0];
        int major = nums[0];
        int count = 1;
        int i = 1;
        while(i<n){
            if(major != nums[i]){
                count--;
                if(i+1<n&&count<1)
                    major = nums[i+1];
            }
            else
                count++;
            i++;
        }
        if(count==0)
            return -1;
        else{
            int maxcount = 0;
            for(int j = 0;j<n;j++)
                if(nums[j]==major)
                    maxcount++;
            if (maxcount>n/2)
                return major;
            else return -1;
        }
    }
}

AC。
學到一種演算法:摩爾投票演算法。該演算法的核心在於抵消,消除不同的數。得到最後留下的數(也就是眾數)。如果全部抵消,則沒有眾數。
//回頭再證明吧
本道題中,眾數不一定是主要元素,但主要元素一定是眾數。(眾數是指一組資料中出現次數最多的數值。主要元素是指一組資料中出現次數超過一半的數值。)

第三次方法
雜湊表,時間複雜度和空間複雜度都是O(n)。

class Solution {
    public int majorityElement(int[] nums) {
        int n = nums.length;
        if (nums == null)
            return -1;
        if (n == 1)
            return nums[0];
        Map<Integer,Integer> map = new HashMap<Integer, Integer>();
        for(int i = 0;i<n;i++){
            if(map.containsKey(nums[i]))
                map.put(nums[i],map.get(nums[i])+1);
            else
                map.put(nums[i],1);
        }
        int maxcount=0,maxelem=-1;
        for (Integer i:map.keySet()){
            if(map.get(i)>maxcount){
                maxelem=i;
                maxcount=map.get(i);
            }
        }
        if (maxcount>n/2)
            return maxelem;
        else
            return -1;
    }
}

AC。效率不如投票演算法。

977. 有序陣列的平方

給你一個按 非遞減順序 排序的整數陣列 nums,返回 每個數字的平方 組成的新陣列,要求也按 非遞減順序 排序。

第一次提交

class Solution {
    public int[] sortedSquares(int[] nums) {
        int p=0;
        for(int i=0;i<nums.length;i++){
            if(nums[i]<0)
                p = i;
            nums[i] = nums[i]*nums[i];
        }
        int []A = new int[nums.length];
        int q=p+1;
        int i=0;
        while(q<nums.length&&p>=0){
            if(nums[p]<nums[q]) {
                A[i] = nums[p];
                p--;
            }
            else{
                A[i] = nums[q];
                q++;
            }
            i++;
        }
        while(q<nums.length){
            A[i] = nums[q];
            q++;i++;
        }
        while(p>=0){
            A[i] = nums[p];
            p--;i++;
        }
        return A;
    }
}

AC。
思路:第一次遍歷的過程中,找到一組資料中負數和整數的分界點,並將平方結果儲存到原陣列中。然後從分界點向左右擴散。

第二次提交

class Solution {
    public int[] sortedSquares(int[] nums) {
        int []res = new int[nums.length];
        int left = 0,right = nums.length-1;
        for(int i = nums.length - 1;i>=0;i--) {
            if (Math.abs(nums[left]) >= Math.abs(nums[right])) {
                res[i] = nums[left] * nums[left];
                left++;
            } else {
                res[i] = nums[right] * nums[right];
                right--;
            }
        }
        return res;
    }
}

AC。
思路:一次遍歷。設定左右兩個指標,比較兩邊的絕對值大小,並從末尾處插入資料。

總結
學到了摩爾投票演算法。用到了雙指標。
回頭證明一下摩爾投票演算法。