Codiwan.com

The blog for Design Patterns, Linux, HA and Myself!

Majority Element Solution - Leetcode

Understand Majority Element (169 Leetcode) with Solution

This document presents the solution to the problem 169. Majority Element - Leetcode.

This problem requires finding the element, from an unsorted array, appearing more than length(array) / 2 times.

There are multiple ways to find the majority element with different size and space complexity based algorithms.

Here’s one approach in which I’ve sorted the array and then counted the presence of the each element.

func majorityElementUsingSort(nums []int) int {
	sort.Ints(nums) // requires importing the sort package.

	current := nums[0]
	currentCount := 0

	majorityElement := nums[0]
	majorityElementCount := 0

	for _, num := range nums {
		if current == num {
			currentCount++
		} else {
			if majorityElementCount < currentCount {
				majorityElement = current
				majorityElementCount = currentCount
			}
			current = num
			currentCount = 1
		}
	}

	return majorityElement
}

Since the array is sorted, I can choose to just create 4 state variable for counting:

How has sorting helped here?

Time Complexity: O(n * log(n)) due to sorting Space Complexity: O(n)

AFAIK, there exists atleast 2 solutions that solve this problem in linear time complexity.

The second approach looked interesting and I choose to implement it.

Approach:

I’ve skipped the 32nd bit position because the input is signed integer array. This is not a correct approach as it does not handle the negative numbers. We will look into the correct approach after discussing the shortcomings in the current approach.

func majorityElementUsingBitWiseOperation(nums []int) int {
	result := 0

	for i := 0; i < 31; i++ {
		currentBitPresenceCount := 0
		for _, num := range nums {
			if num&(1<<i) == (1 << i) {
				currentBitPresenceCount++
			}
		}

		if currentBitPresenceCount > len(nums)/2 {
			result |= 1 << i
		}

		currentBitPresenceCount = 0
	}

	return result
}

Why does it not work with negative numbers?

In two’s complement representation:

This representation breaks the logic.

Here’s the solution that handles the negative numbers too:

func majorityElementUsingBitWiseOperation(nums []int) int {
	negativeCount := 0
	result := 0

	for i := 0; i < 31; i++ {
		currentBitPresenceCount := 0
		for _, num := range nums {
			if num < 0 {
				if i == 30 {
					negativeCount++
				}
				num = -num
			}
			if num&(1<<i) == (1 << i) {
				currentBitPresenceCount++
			}
		}

		if currentBitPresenceCount > len(nums)/2 {
			result |= 1 << i
		}

		currentBitPresenceCount = 0
	}

	if negativeCount > len(nums)/2 {
		return -result
	}

	return result
}

Changes:

Please do provide some comments if you find the explanation a bit lacking.

Loading Comments... Disqus Loader
comments powered by Disqus