Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions Algorithms.Tests/Other/BoyerMooreMajorityVoteTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using Algorithms.Other;
using NUnit.Framework;
using FluentAssertions;

namespace Algorithms.Tests.Other;

public class BoyerMooreMajorityVoteTests
{
[Test]
public void FindMajority_SimpleMajority_ReturnsCorrectElement()
{
var nums = new[] { 3, 3, 4, 2, 3, 3, 3 };
var result = BoyerMooreMajorityVote.FindMajority(nums);
result.Should().Be(3);
}

[Test]
public void FindMajority_AllSameElements_ReturnsThatElement()
{
var nums = new[] { 5, 5, 5, 5 };
var result = BoyerMooreMajorityVote.FindMajority(nums);
result.Should().Be(5);
}

[Test]
public void FindMajority_NoMajority_ReturnsNull()
{
var nums = new[] { 1, 2, 3, 4 };
var result = BoyerMooreMajorityVote.FindMajority(nums);
result.Should().BeNull();
}

[Test]
public void FindMajority_EmptyArray_ReturnsNull()
{
var nums = Array.Empty<int>();
var result = BoyerMooreMajorityVote.FindMajority(nums);
result.Should().BeNull();
}

[Test]
public void FindMajority_NullArray_ReturnsNull()
{
int[]? nums = null;
var result = BoyerMooreMajorityVote.FindMajority(nums!);
result.Should().BeNull();
}

[Test]
public void FindMajority_SingleElement_ReturnsThatElement()
{
var nums = new[] { 7 };
var result = BoyerMooreMajorityVote.FindMajority(nums);
result.Should().Be(7);
}

[Test]
public void FindMajority_MajorityAtEnd_ReturnsCorrectElement()
{
var nums = new[] { 1, 2, 2, 2, 2 };
var result = BoyerMooreMajorityVote.FindMajority(nums);
result.Should().Be(2);
}

[Test]
public void FindMajority_MajorityAtStart_ReturnsCorrectElement()
{
var nums = new[] { 8, 8, 8, 8, 1, 2 };
var result = BoyerMooreMajorityVote.FindMajority(nums);
result.Should().Be(8);
}

[Test]
public void FindMajority_NegativeNumbers_ReturnsCorrectElement()
{
var nums = new[] { -1, -1, -1, 2, 2 };
var result = BoyerMooreMajorityVote.FindMajority(nums);
result.Should().Be(-1);
}

[Test]
public void FindMajority_ExactlyHalf_ReturnsNull()
{
var nums = new[] { 1, 1, 2, 2 };
var result = BoyerMooreMajorityVote.FindMajority(nums);
result.Should().BeNull();
}
}
45 changes: 45 additions & 0 deletions Algorithms/Other/BoyerMooreMajorityVote.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
namespace Algorithms.Other;

/// <summary>
/// Boyer-Moore Majority Vote algorithm.
/// Finds element appearing more than n/2 times in O(n) time, O(1) space.
/// </summary>
public static class BoyerMooreMajorityVote
{
/// <summary>
/// Finds the majority element.
/// </summary>
/// <param name="nums">Input array.</param>
/// <returns>Majority element or null.</returns>
public static int? FindMajority(int[] nums)
{
if (nums == null || nums.Length == 0)
{
return null;
}

var candidate = FindCandidate(nums);
return IsMajority(nums, candidate) ? candidate : null;
}

private static int FindCandidate(int[] nums)
{
int candidate = nums[0];
int count = 1;

for (int i = 1; i < nums.Length; i++)
{
if (count == 0)
{
candidate = nums[i];
}

count += nums[i] == candidate ? 1 : -1;
}

return candidate;
}

private static bool IsMajority(int[] nums, int candidate) =>
nums.Count(n => n == candidate) > nums.Length / 2;
}