[编程题] 微信红包
春节期间小明使用微信收到很多个红包,非常开心。在查看领取红包记录时发现,某个红包金额出现的次数超过了红包总数的一半。请帮小明找到该红包金额。写出具体算法思路和代码实现,要求算法尽可能高效。
给定一个红包的金额数组gifts及它的大小n,请返回所求红包的金额。
测试样例:
[1,2,3,2,2],5
返回:2
思想:
消去法直接解答。遍历数组,把不等的两个元素消掉,最后剩下的元素即使答案
C++代码:
// gift.cpp : 定义控制台应用程序的入口点。
//
#include<vector>
#include<iostream>
using namespace std;
class Gift {
public:
int getValue(vector<int> gifts, int n) {
// write code here
bool* remove = new bool[n];
memset(remove, 0, sizeof(bool)*n);
int i = 0;
int j = 0;
while (j < n) {
if (j == i) {
j++;
}
if (j >= n) break;
if (gifts[i] == gifts[j]) {
j++;
}
else {
remove[i] = remove[j] = true;
while (i < n && remove[i]) {
i++;
}
j++;
}
}
int index = n - 1;
for (; index >= 0 && remove[index]; index--);
delete[] remove;
return gifts[index];
}
};
int main()
{
Gift gf = Gift();
vector<int> gifts = vector<int>({ 1,1,1,1,1, 2, 2, 2,3 });
int value = gf.getValue(gifts, gifts.size());
cout << value << endl;
return 0;
}
利用 bool* remove = new bool[n] 创建bool数组;
利用 delete[] remove 删除 new 创建的数组;
利用 memset 函数,把数组元素设置为0;
false转成整数值是0;
Go语言:
package main
import (
"fmt"
)
func main() {
gifts := []int{1, 2, 3, 4, 5, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1}
g := Gift(gifts, 1)
fmt.Println(g)
}
func Gift(gifts []int, n int) int {
remove := make([]bool, n)
for i := 0; i < n; i++ {
remove[i] = false
}
i, j := 0, 0
for {
if i == j {
j++
}
if j >= n {
break
}
if gifts[i] != gifts[j] {
remove[i] = true
remove[j] = true
for i < n && remove[i] {
i++
}
}
j++
}
index := n - 1
for ; index >= 0 && remove[index]; index-- {
}
return gifts[index]
}
语言要点:
make([]bool, n) 创建数组
Python代码:
# -*- coding: utf-8 -*-
def gift(gifts):
n = len(gifts)
remove = [False for i in range(n)]
i = j = 0
while True:
if i == j:
j += 1
if j >= n:
break
if gifts[i] != gifts[j]:
remove[i] = remove[j] = True
while i < n and remove[i]:
i += 1
j += 1
index = n - 1
while index >= 0 and remove[index]:
index -= 1
return gifts[index]
if __name__ == "__main__":
g = gift([1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2])
print(g)