【四种解法】剑指 Offer 39. 数组中出现次数超过一半的数字
立志用最少的代碼做最高效的表達(dá)
數(shù)組中有一個數(shù)字出現(xiàn)的次數(shù)超過數(shù)組長度的一半,請找出這個數(shù)字。
你可以假設(shè)數(shù)組是非空的,并且給定的數(shù)組總是存在多數(shù)元素。
示例 1:
輸入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
輸出: 2
限制:
1 <= 數(shù)組長度 <= 50000
代碼一:HashMap
做法:利用hashmap統(tǒng)計次數(shù),最后輸出出現(xiàn)次數(shù)最多的變量
時間復(fù)雜度:O(n)
空間復(fù)雜度:O(n)
顯而易見的缺點:沒有利用“出現(xiàn)次數(shù)超過一半”這個條件
static class Solution1 {public int maxCount(int[] nums) {if(nums.length == 0) return -1;Map<Integer, Integer> map = new HashMap<>();int max = 0, max_value = -0x7fffffff, len = nums.length;for(int i = 0; i < len; i++) {if(map.putIfAbsent(nums[i],1) != null) // 如果為空,則賦值為0map.put(nums[i], map.get(nums[i])+1);if(max_value < map.get(nums[i])) { max_value = map.get(nums[i]); max = nums[i]; }}return max;}}代碼二:針對代碼一的優(yōu)化
針對思路一的優(yōu)化:因為出現(xiàn)次數(shù)超過一半即可,因此無需遍歷完整張表,當(dāng)某個值出現(xiàn)次數(shù)超過一半,結(jié)束循環(huán),輸出即可。
時間復(fù)雜度:O(n/2)~O(n)
空間復(fù)雜度:O(n)
代碼三:排序算法
由于出現(xiàn)次數(shù)超過一半,因此排序后,數(shù)組的中間值一定為該數(shù)。
時間復(fù)雜度:O(nlogn)
空間復(fù)雜度:O(1)
代碼四:摩爾投票法
可以理解為同歸于盡大法,一個對一個,最后活下來的一定是出現(xiàn)次數(shù)超過一半的
class Solution {public int majorityElement(int[] nums) {int res = 0, count = 0;for(int i : nums)if(count == 0) {res = i; count++;}elsecount += (res==i ? 1 : -1);return res;} }完整可運行Java代碼
import java.util.Arrays; import java.util.HashMap; import java.util.Map;public class 劍指Offer39_數(shù)組中次數(shù)超一半的數(shù)字 {// 1、hashmap:雙O(n)// 做法:利用hashmap統(tǒng)計次數(shù),最后輸出出現(xiàn)次數(shù)最多的變量// 顯而易見的缺點:沒有利用“出現(xiàn)次數(shù)超過一半”這個條件static class Solution1 {public int maxCount(int[] nums) {if(nums.length == 0) return -1;Map<Integer, Integer> map = new HashMap<>();int max = 0, max_value = -0x7fffffff, len = nums.length;for(int i = 0; i < len; i++) {if(map.putIfAbsent(nums[i],1) != null) // 如果為空,則賦值為0map.put(nums[i], map.get(nums[i])+1);if(max_value < map.get(nums[i])) { max_value = map.get(nums[i]); max = nums[i]; }}return max;}}// 2、針對思路一的優(yōu)化;因為出現(xiàn)次數(shù)超過一半即可,因此無需遍歷完整張表,當(dāng)某個值出現(xiàn)次數(shù)超過一半,結(jié)束循環(huán),輸出即可。// 時間O(n/2),空間O(n)static class Solution2 {public int maxCount(int[] nums) {Map<Integer, Integer> map = new HashMap<>();int max = 0, max_value = -0x7fffffff, len = nums.length;for(int i = 0; i < len; i++) {if(map.putIfAbsent(nums[i],1) != null) // 如果為空,則賦值為0map.put(nums[i], map.get(nums[i])+1);if(map.get(nums[i]) > len/2)return nums[i];}return -1;}}// 3、排序:O(nlogn)、O(1)static class Solution3 {public int maxCount(int[] nums) {Arrays.sort(nums);return nums[nums.length/2];}}// 4、摩爾投票法,可以理解為同歸于盡大法,一個對一個,最后活下來的一定是出現(xiàn)次數(shù)超過一半的static class Solution4 {public int majorityElement(int[] nums) {int res = 0, count = 0;for(int i : nums)if(count == 0) {res = i; count++;}elsecount += (res==i ? 1 : -1);return res;}}public static void main(String[] args) {} }總結(jié)
以上是生活随笔為你收集整理的【四种解法】剑指 Offer 39. 数组中出现次数超过一半的数字的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【易懂】Java源码角度分析put()与
- 下一篇: 【终极办法】org.springfram