字典实现:python-----VS----java
对比python和java的字典数据结构,以下就LeetCode面试题 17.10. 主要元素为栗子,进行学习。是一道简单题目,重点看数据结构的运用与实现。
普通的思路,使用一个字典结构记录每个元素出现的次数,然后判别每个元素出现次数是否超过数组长度的一半(绝对大于)。
python实现dict:我们可以看到,非常简单灵活,而又清晰
1 class Solution: 2 def majorityElement(self, nums: List[int]) -> int: 3 if not nums: return -1 4 hashtable = {} 5 n = len(nums) 6 for i in range(n): 7 if nums[i] not in hashtable.keys(): 8 hashtable[nums[i]] = 1 9 else: 10 hashtable[nums[i]] += 1 11 if hashtable[nums[i]] > n//2: 12 return nums[i] 13 return -1
java使用HashMap实现dict逻辑:重点要注意HashMapde的定义,Integer不能写成int(亲测会报错)。判断元素是否存在使用HashMap.containsKey()函数;得到相应元素使用get函数,改变指定元素使用put函数。
1 class Solution { 2 public int majorityElement(int[] nums) { 3 HashMap<Integer, Integer> hashtable = new HashMap<>(); 4 int n = nums.length; 5 for(int i = 0; i < n; i++){ 6 if (hashtable.containsKey(nums[i])){ 7 int tmp = hashtable.get(nums[i]); 8 tmp++; 9 hashtable.put(nums[i], tmp); 10 }else{ 11 hashtable.put(nums[i], 1); 12 } 13 if(hashtable.get(nums[i]) > n/2){ 14 return nums[i]; 15 } 16 } 17 return -1; 18 } 19 }
第三行代码可以使用Map(父类)进行定义:
Map<Integer, Integer> hashtable = new HashMap<>();
发现了java更简洁的写法,使用了HashMap中的getOrDefault方法。
1 class Solution { 2 public int majorityElement(int[] nums) { 3 Map<Integer,Integer> map=new HashMap<>(); 4 for(int i=0;i<nums.length;i++) { 5 map.put(nums[i], map.getOrDefault(nums[i],0)+1); 6 if(map.get(nums[i])>nums.length/2)return nums[i]; 7 } 8 return -1; 9 10 } 11 } 12 13 作者:camile8 14 链接:https://leetcode-cn.com/problems/find-majority-element-lcci/solution/zhi-xing-yong-shi-20-msnei-cun-xiao-hao-442-mb-by-/ 15 来源:力扣(LeetCode) 16 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
小小台阶:题目有个小进阶,如下图
首先做个井底之蛙,不看大佬的算法讲解,先排序,然后使用pre和count进行元素数量的记录,最后判断,因为排序最小的时间复杂度是nlog(n),因此需要进行算法优化啦,:
1 class Solution: 2 def majorityElement(self, nums: List[int]) -> int: 3 nums.sort() 4 if not nums: return -1 5 pre = nums[0] 6 index = 1 7 count = 1 8 while index < len(nums): 9 if nums[index] == pre: 10 count += 1 11 else: 12 pre = nums[index] 13 count = 1 14 index += 1 15 if count > len(nums)//2: 16 return pre 17 if count > len(nums)//2: 18 return pre 19 return -1
java实现:java实现涉及几个知识点,首先,java的排序,然后呢,java的for循环数组遍历。这里呢,我们对list进行排序,使用Arrays类的sort方法。
1 class Solution { 2 public int majorityElement(int[] nums) { 3 Arrays.sort(nums); 4 if(nums == null){return -1;} 5 int pre = nums[0], count = 1; 6 for(int i = 1; i < nums.length; i++){ 7 if(nums[i] == pre){ 8 count++; 9 }else{ 10 pre = nums[i]; 11 count = 1; 12 } 13 if (count > nums.length/2){ 14 return nums[i]; 15 } 16 } 17 if (count > nums.length/2){ 18 return pre; 19 } 20 return -1; 21 } 22 }
算法优化:利用找众数的思想,“世界男人分两种,我和我以外的”,特殊情况下[1, 2, 2, 3, 3, 3],需要进行验证,存在的众数数量是否大于总量一半。
python代码:
1 class Solution: 2 def majorityElement(self, nums: List[int]) -> int: 3 n = len(nums) 4 if n==0: return -1 5 tmp, count = nums[0], 1 6 for i in range(1, n): 7 if nums[i] == tmp: 8 count += 1 9 else: 10 count -= 1 11 if count == 0: 12 tmp = nums[i] 13 count = 1 14 if count==0: return -1 15 half_num = n //2 + 1 16 count = 0 17 for i in range(n): 18 if nums[i] == tmp: 19 count += 1 20 if count == half_num: 21 return tmp 22 return -1
java代码:
1 class Solution { 2 public int majorityElement(int[] nums) { 3 int n = nums.length; 4 if(n==0){return -1;} 5 int tmp = nums[0], count = 1; 6 for(int i = 1; i < n; i++){ 7 if(nums[i]==tmp){ 8 count++; 9 } 10 else{ 11 count--; 12 } 13 if(count==0){ 14 tmp = nums[i]; 15 count = 1; 16 } 17 } 18 if(count == 0){ return -1;} 19 int half_n = n/2 + 1; 20 count = 0; 21 for(int i = 0; i < n; i++){ 22 if(nums[i] == tmp){count++;} 23 if(count==half_n){ 24 return tmp; 25 } 26 } 27 return -1; 28 } 29 }