保证数组输入非空,且保证有解
[1,2,3,2,2,2,5,4,2]
2
[3,3,3,3,2,2,2]
3
[1]
1
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers)
{
// 因为用到了sort,时间复杂度O(NlogN),并非最优
if(numbers.empty()) return 0;
sort(numbers.begin(),numbers.end()); // 排序,取数组中间那个数
int middle = numbers[numbers.size()/2];
int count=0; // 出现次数
for(int i=0;i<numbers.size();++i)
{
if(numbers[i]==middle) ++count;
}
return (count>numbers.size()/2) ? middle : 0;
}
};
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers)
{
if(numbers.empty()) return 0;
// 遍历每个元素,并记录次数;若与前一个元素相同,则次数加1,否则次数减1
int result = numbers[0];
int times = 1; // 次数
for(int i=1;i<numbers.size();++i)
{
if(times == 0)
{
// 更新result的值为当前元素,并置次数为1
result = numbers[i];
times = 1;
}
else if(numbers[i] == result)
{
++times; // 相同则加1
}
else
{
--times; // 不同则减1
}
}
// 判断result是否符合条件,即出现次数大于数组长度的一半
times = 0;
for(int i=0;i<numbers.size();++i)
{
if(numbers[i] == result) ++times;
}
return (times > numbers.size()/2) ? result : 0;
}
};
import java.util.*;
public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
int[] a=new int[10000];
for(int i=0;i<array.length;i++){
a[ array[i] ]+=1;
}
float num=array.length/2;
for(int i=0;i<10000;i++){
if(a[i] > num) return i;
}
return 0;
}
} function MoreThanHalfNum_Solution(numbers) {
// write code here
if (numbers.length === 1) return numbers[0];
let map = new Map();
for (let i = 0; i < numbers.length; i++) {
if (map[numbers[i]]) {
map[numbers[i]] += 1;
} else {
map[numbers[i]] = 1;
}
}
for (let key in map) {
if (map[key] > numbers.length / 2) return key;
}
}
module.exports = {
MoreThanHalfNum_Solution: MoreThanHalfNum_Solution,
};
public int MoreThanHalfNum_Solution(int [] array) {
//摩尔投票法
int n = array.length;
int count = 0;
int res = -1;
for (int i = 0; i < n; i++) {
if (count == 0){
res = array[i];
count ++;
}else if (array[i] != res){
count--;
}else if (array[i] == res){
count ++;
}
}
return res;
} import java.util.*;
public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
int ans = 0;
HashMap<Integer,Integer> map = new HashMap<>();
for (int num: array) {
if (map.containsKey(num)){
int count = map.get(num);
count++;
if (count > array.length/2){
ans = num;
break;
}
map.put(num,count);
}else {
map.put(num,1);
}
}
if (map.size() == 1){
return array[0];
}
return ans;
}
} 在保证一定有解的情况下,可以使用这种方法 时间复杂度O(n) 空间复杂度O(1)
class Solution:
def MoreThanHalfNum_Solution(self , numbers: List[int]) -> int:
temp = -1
cnt = 0
for num in numbers:
if cnt == 0:
temp = num
cnt += 1
else:
if num == temp:
cnt += 1
else:
cnt -= 1
return temp哈希法
时间复杂度:O(n) 空间复杂度O(n)
class Solution:
def MoreThanHalfNum_Solution(self , numbers: List[int]) -> int:
n = len(numbers)
mp = {}
for num in numbers:
if num not in mp:
mp[num] = 1
else:
mp[num] += 1
if mp[num] >= n / 2:
return num
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
int count = 1;
int cur = numbers[0];
int pre = 0;
for(int i = 1;i < numbers.size();i++){
if(numbers[i]!=cur&&count==1){
if(pre==numbers[i]){
cur = pre;
count++;
}
else{
pre = cur;
cur = numbers[i];
}
}
else if(numbers[i]!=cur){
count--;
}
else{
count++;
}
}
return cur;
}
}; class Solution:
def MoreThanHalfNum_Solution(self , numbers: List[int]) -> int:
half_len = len(numbers)/2
num_dic = {}
for i in numbers :
num_dic[i] = num_dic.get(i, 0) + 1
if num_dic[i] >= half_len :
return i import java.util.*;
public class Solution {
// HashMap计数
// 时间复杂度O(n)
// 空间复杂度O(n)
public int MoreThanHalfNum_Solution(int[] array) {
if (array == null || array.length == 0) {
return -1;
}
// 处理数组长度只有1的特殊情况
if (array.length == 1) {
return array[0];
}
int threshold = array.length / 2;
Map<Integer, Integer> cntMap = new HashMap<>();
for (int num : array) {
Integer cnt = cntMap.get(num);
if (cnt == null) {
cntMap.put(num, 1);
} else if (cnt == threshold) {
return num;
} else {
cntMap.put(num, cnt + 1);
}
}
return -1;
}
}
如果先对数组进行排序,那么出现次数超过一半的元素一定是数组的中位数,也就是排序后下标为n/2的那个元素(n为偶数时n/2是中间偏右的那个元素,n为奇数时n/2就是中间元素),所以我们的目标就是找到排序后下标为n/2的那个元素。这其实可以借助快速排序来实现:
快排的分区函数每次找到一个pivot放到数组的适当位置,将数组分为左右两个部分,左边元素都小于pivot,右边元素都大于pivot。此时如果pivot的下标i正好是n/2,那pivot就是出现次数超过一半的那个元素,返回它即可;如果i<n/2,那就对i的右半部分执行分区函数;如果i>n/2,那就对i的左半部分执行分区函数。总之最终一定能找到i==n/2的目标元素,《剑指Offer》给出的时间复杂度是O(n)。
public class Solution {
// 快速排序思想
// 时间复杂度O(n)
// 空间复杂度O(1)
public int MoreThanHalfNum_Solution(int[] array) {
if (array == null || array.length == 0) {
return -1;
}
int l = 0, r = array.length - 1;
int target = array.length / 2;
while (true) {
int mid = partition(array, l, r);
if (target == mid) {
return array[target];
} else if (target > mid) {
l = mid + 1;
} else {
r = mid - 1;
}
}
}
// 快排的分区函数
public int partition(int[] array, int l, int r) {
int i = l, j = r, pivot = array[l];
while (i < j) {
while (i < j && array[j] >= pivot) {
j--;
}
array[i] = array[j];
while (i < j && array[i] < pivot) {
i++;
}
array[j] = array[i];
}
array[i] = pivot;
return i;
}
} 我们首先给出 Boyer-Moore 算法的详细步骤:
维护一个候选众数candidate和它出现的次数count。初始时candidate为首元素,count为 0;
我们遍历数组array中的所有元素,对于每个元素 x,进行如下判断:
在判断 x 之前,如果count的值为 0,我们先将 x 的值赋予candidate,随后我们判断 x:
如果 x 与candidate相等,那么计数器count的值增加 1;
如果 x 与candidate不等,那么计数器count的值减少 1。
在遍历完成后,candidate即为整个数组的众数。
public class Solution {
// 投票算法
// 我个人觉得就是把本来对自己+1的票数,转化为对候选者的票数-1,这就等同于变相给自己投票了
// 时间复杂度O(n)
// 空间复杂度O(1)
public int MoreThanHalfNum_Solution(int[] array) {
if (array == null || array.length == 0) {
return -1;
}
int candidate = array[0], cnt = 1;
for (int i = 1; i < array.length; i++) {
if (candidate == array[i]) { // 候选者票数+1
cnt++;
} else if (cnt > 0) { // 候选者票数-1, 相当于变相对array[i]的票数+1
cnt--;
} else { // 暂时没有候选者, 那就让array[i]作为候选者, 票数为1
candidate = array[i];
cnt = 1;
}
}
return candidate;
}
} 暴力循环...
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
if(numbers.size() == 1 || numbers.size() == 2){
return numbers[0];
}
for(int i = 0; i < numbers.size(); i++){
int c = 0;
for(int j = 0; j < numbers.size(); j++){
if(numbers[j] - numbers[i] == 0 && j != i)
c++;
}
if(c + 1 > numbers.size() / 2){
return numbers[i];
}
}
return 0;
}
}; public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
//摩尔投票
int cnt = 0;
int candidate = 0;
for(int num : array){
if(cnt == 0)
candidate = num;
cnt += candidate == num ? 1 : -1;
}
return candidate;
}
} function MoreThanHalfNum_Solution(numbers)
{
// write code here
var count = 0;
var res = 0;
for (var i = 0; i < numbers.length; i++) {
if (count == 0) {
res = numbers[i];
}
if (numbers[i] == res) {
count++;
} else {
count--;
}
}
console.log(res);
return res;
}
module.exports = {
MoreThanHalfNum_Solution : MoreThanHalfNum_Solution
}; function MoreThanHalfNum_Solution(numbers)
{
// write code here
if (numbers.length == 1) {
return numbers[numbers.length - 1];
}
// 排序
numbers.sort();
// 新建一个对象 将每个数出现的次数与此数组成键值对
var obj = {}
for (var i = 0; i < numbers.length; i++) {
if (numbers[i] == numbers[i + 1] && numbers[i] != numbers[i - 1]) {//判断是否重复,是否已经放入容器
var result = numbers[i];
// console.log(result);
var count = numbers.lastIndexOf(result) - numbers.indexOf(result) + 1;
// console.log(count);
// count 与 result组成键值对 做一个绑定
obj[count] = result
// console.log(obj[count]);
}
}
// 此时对象中的key 是 count
// 先获取到最大的key 与 numbers.length / 2 作比较
// 最终通过key获取value 这样就不会出现错乱了
if (Math.max.apply(null, Object.keys(obj)) >= numbers.length / 2) {
return obj[Math.max.apply(null, Object.keys(obj))];
}
else {
return -1;
}
}
module.exports = {
MoreThanHalfNum_Solution : MoreThanHalfNum_Solution
}; class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
if(numbers.size() <= 0) return 0;
int ans = 0;
int cnt = 0;
for(int i = 0; i < numbers.size(); ++i)
{
if(cnt == 0)
ans = numbers[i], ++cnt;
else{
if(ans != numbers[i])
--cnt;
else
++cnt;
}
}
return ans;
}
}; int MoreThanHalfNum_Solution(vector<int> numbers) {
int index = 0;
int value = 0;
for(int i = 0; i < numbers.size();i++){
if(index==0) {
value = numbers[i];
index++;
} else {
if(value==numbers[i]) index++;
else index--;
}
}
return value;
}
public int MoreThanHalfNum_Solution(int [] array) {
int length=array.length;
if(array==null||length<=0){
return 0;
}
if(length==1){
return array[1];
}
int[] tempArray=new int[length];
for(int i=0;i<length;i++){
tempArray[i]=array[i];
}
for(int i=0;i<length;i++){
//后面需要用零来代表抹除数字,所以对0时做特殊处理
if(tempArray[i]==0){
continue;
}
for(int j=i+1;j<length;j++){
if(tempArray[i]!=tempArray[j]&&tempArray[j]!=0){
tempArray[i]=0;//此处用0代表抹去该数字
tempArray[j]=0;
break;
}
}
}
for(int i=0;i<length;i++){
System.out.println(tempArray[i]);
}
//找出未被抹去的数字
int result=0;
for(int i=0;i<length;i++){
if(tempArray[i]!=0){
result=tempArray[i];
break;
}
}
int times=0;
for(int i=0;i<length;i++){
if(result==array[i]){
times++;
}
}
if(times*2<length){
result=0;
}
return result;
}
}
public int MoreThanHalfNum_Solution(int [] array) {
int length=array.length;
if(array==null||length<=0){
return 0;
}
int result=array[0];
int times=1;
for(int i=1;i<length;i++){
if(times==0){
result=array[i];
times=1;
}else{
if(array[i]==result){
times++;
}else{
times--;
}
}
}
times=0;
for(int i=0;i<length;i++){
if(result==array[i]){
times++;
}
}
if(times*2<length){
result=0;
}
return result;
}
}