题目
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。
思路
- 快排partition方法(剑指OFFER解法1)
- obj保存每个数字出现的次数
- 遍历times(剑指OFFER解法2)
// 1
function MoreThanHalfNum_Solution(numbers) {
// write code here
if (!numbers.length) {
return 0
}
let mid = Math.floor(numbers.length / 2)
let index = partition(numbers, 0, numbers.length - 1)
let i = 0
let j = numbers.length - 1
while (mid !== index) {
if (index < mid) {
i = index + 1
index = partition(numbers, i, j)
} else {
j = index - 1
index = partition(numbers, i, j)
}
}
return checkHalf(numbers, numbers[mid]) ? numbers[mid] : 0
}
function checkHalf(arr, num) {
let counts = 0
for (let item of arr) {
if (item === num) {
counts++
}
}
if (counts > Math.floor(arr.length / 2)) {
return true
}
return false
}
function partition(arr, left, right) {
let privot = arr[left]
while (left <= right) {
if (left <= right && arr[right] >= privot) {
right--
}
swap(arr, left, right)
if (left <= right && arr[left] <= privot) {
left++
}
swap(arr, left, right)
}
return left
}
function swap(arr, i, j) {
let temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
}
// 2
function MoreThanHalfNum_Solution(numbers)
{
// write code here
let obj = {}
let flag = false
for(let i = 0; i < numbers.length; i++) {
if(!obj[numbers[i]]) {
obj[numbers[i]] = 1
} else {
++obj[numbers[i]]
}
if (obj[numbers[i]] > Math.floor(numbers.length / 2)) {
return numbers[i]
}
}
return 0
}
// 3
function MoreThanHalfNum_Solution(numbers) {
// write code here
let times = 0
let result = numbers[0]
for (let i = 1; i < numbers.length; i++) {
if (times === 0) {
result = numbers[i]
times = 1
continue
}
if (numbers[i] !== result) {
times--
} else {
times++
}
}
return checkMorethanHalf(numbers, result) ? result : 0
}
function checkMorethanHalf(arr, num) {
let counts = 0
for (let i = 0; i < arr.length; i++) {
if (arr[i] === num) {
counts++
}
}
if (counts > Math.floor(arr.length / 2)) {
return true
}
return false
}