LeetCode刷題之陣列篇day2
阿新 • • 發佈:2021-01-05
面試題 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。
思路:一次遍歷。設定左右兩個指標,比較兩邊的絕對值大小,並從末尾處插入資料。
總結
學到了摩爾投票演算法。用到了雙指標。
回頭證明一下摩爾投票演算法。