Online Majority Element In Subarray Solutions in Go
Number 1157
Difficulty Hard
Acceptance 39.1%
Link LeetCode
Other languages C++
Solutions
Go solution by halfrost/LeetCode-Go
package leetcodeimport ("sort")type segmentItem struct {candidate intcount int}// MajorityChecker definetype MajorityChecker struct {segmentTree []segmentItemdata []intmerge func(i, j segmentItem) segmentItemcount map[int][]int}// Constructor1157 definefunc Constructor1157(arr []int) MajorityChecker {data, tree, mc, count := make([]int, len(arr)), make([]segmentItem, 4*len(arr)), MajorityChecker{}, make(map[int][]int)// 这个 merge 函数就是摩尔投票算法mc.merge = func(i, j segmentItem) segmentItem {if i.candidate == j.candidate {return segmentItem{candidate: i.candidate, count: i.count + j.count}}if i.count > j.count {return segmentItem{candidate: i.candidate, count: i.count - j.count}}return segmentItem{candidate: j.candidate, count: j.count - i.count}}for i := 0; i < len(arr); i++ {data[i] = arr[i]}for i := 0; i < len(arr); i++ {if _, ok := count[arr[i]]; !ok {count[arr[i]] = []int{}}count[arr[i]] = append(count[arr[i]], i)}mc.data, mc.segmentTree, mc.count = data, tree, countif len(arr) > 0 {mc.buildSegmentTree(0, 0, len(arr)-1)}return mc}func (mc *MajorityChecker) buildSegmentTree(treeIndex, left, right int) {if left == right {mc.segmentTree[treeIndex] = segmentItem{candidate: mc.data[left], count: 1}return}leftTreeIndex, rightTreeIndex := mc.leftChild(treeIndex), mc.rightChild(treeIndex)midTreeIndex := left + (right-left)>>1mc.buildSegmentTree(leftTreeIndex, left, midTreeIndex)mc.buildSegmentTree(rightTreeIndex, midTreeIndex+1, right)mc.segmentTree[treeIndex] = mc.merge(mc.segmentTree[leftTreeIndex], mc.segmentTree[rightTreeIndex])}func (mc *MajorityChecker) leftChild(index int) int {return 2*index + 1}func (mc *MajorityChecker) rightChild(index int) int {return 2*index + 2}// Query definefunc (mc *MajorityChecker) query(left, right int) segmentItem {if len(mc.data) > 0 {return mc.queryInTree(0, 0, len(mc.data)-1, left, right)}return segmentItem{candidate: -1, count: -1}}func (mc *MajorityChecker) queryInTree(treeIndex, left, right, queryLeft, queryRight int) segmentItem {midTreeIndex, leftTreeIndex, rightTreeIndex := left+(right-left)>>1, mc.leftChild(treeIndex), mc.rightChild(treeIndex)if queryLeft <= left && queryRight >= right { // segment completely inside rangereturn mc.segmentTree[treeIndex]}if queryLeft > midTreeIndex {return mc.queryInTree(rightTreeIndex, midTreeIndex+1, right, queryLeft, queryRight)} else if queryRight <= midTreeIndex {return mc.queryInTree(leftTreeIndex, left, midTreeIndex, queryLeft, queryRight)}// merge query resultsreturn mc.merge(mc.queryInTree(leftTreeIndex, left, midTreeIndex, queryLeft, midTreeIndex),mc.queryInTree(rightTreeIndex, midTreeIndex+1, right, midTreeIndex+1, queryRight))}// Query definefunc (mc *MajorityChecker) Query(left int, right int, threshold int) int {res := mc.query(left, right)if _, ok := mc.count[res.candidate]; !ok {return -1}start := sort.Search(len(mc.count[res.candidate]), func(i int) bool { return left <= mc.count[res.candidate][i] })end := sort.Search(len(mc.count[res.candidate]), func(i int) bool { return right < mc.count[res.candidate][i] }) - 1if (end - start + 1) >= threshold {return res.candidate}return -1}/*** Your MajorityChecker object will be instantiated and called as such:* obj := Constructor(arr);* param_1 := obj.Query(left,right,threshold);*/