技術類編程題彙總 C++ 刷題記錄

騰訊2018春招技術類編程題彙總

1、翻轉數列

小Q定義了一種數列稱爲翻轉數列:
給定整數n和m, 滿足n能被2m整除。對於一串連續遞增整數數列1, 2, 3, 4…, 每隔m個符號翻轉一次, 最初符號爲’-’;。
例如n = 8, m = 2, 數列就是: -1, -2, +3, +4, -5, -6, +7, +8.
而n = 4, m = 1, 數列就是: -1, +2, -3, + 4.
小Q現在希望你能幫他算算前n項和爲多少。

輸入描述:
輸入包括兩個整數n和m(2 <= n <= 109, 1 <= m), 並且滿足n能被2m整除。

輸出描述:
輸出一個整數, 表示前n項和。

輸入例子1:
8 2

輸出例子1:
8

#include <iostream>
using namespace std;

// 暴力法 case通過率爲80.00%,超時
long long fun(int n, int m) {
	long long res = 0;
	int k = 0, flag = -1;
	for (int i = 0; i < n/m; i++){
		for (int j = 0; j < m; j++){
			k = flag * (abs(k) + 1);
			res += k;
		}
		flag *= -1;
	}
	return res;
}

// 找規律:第一個加號值加上第一個減號值,差值剛好是m,共有n/2對
// -1, -2, +3, +4, -5, -6, +7, +8
long long fun2(int n, int m) {
    return n/2*m;
}

int main() {
	int n, m;
	cin >> n >> m;

	cout << fun2(n,m) << endl;
	return 0;
}

2、紙牌遊戲

牛牛和羊羊正在玩一個紙牌遊戲。這個遊戲一共有n張紙牌, 第i張紙牌上寫着數字ai。
牛牛和羊羊輪流抽牌, 牛牛先抽, 每次抽牌他們可以從紙牌堆中任意選擇一張抽出, 直到紙牌被抽完。
他們的得分等於他們抽到的紙牌數字總和。
現在假設牛牛和羊羊都採用最優策略, 請你計算出遊戲結束後牛牛得分減去羊羊得分等於多少。

輸入描述:
輸入包括兩行。
第一行包括一個正整數n(1 <= n <= 105),表示紙牌的數量。
第二行包括n個正整數ai(1 <= ai <= 109),表示每張紙牌上的數字。

輸出描述:
輸出一個整數, 表示遊戲結束後牛牛得分減去羊羊得分等於多少。

輸入例子1:
3
2 7 4

輸出例子1:
5

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

int main(){
	int n;
	cin >> n;
	priority_queue<int, vector<int>,less<int>> card;
	int t;
	for (int i = 0; i < n; i++){
		cin >> t;
		card.push(t);
	}

	int res = 0;
	int flag = 1;
	while (!card.empty()){
		int c = card.top();
		res += flag*c;
		flag *= -1;
		card.pop();
	}
	cout << res << endl;
	return 0;
}

3、貪喫的小Q

小Q的父母要出差N天,走之前給小Q留下了M塊巧克力。小Q決定每天喫的巧克力數量不少於前一天喫的一半,但是他又不想在父母回來之前的某一天沒有巧克力喫,請問他第一天最多能喫多少塊巧克力

輸入描述:
每個輸入包含一個測試用例。
每個測試用例的第一行包含兩個正整數,表示父母出差的天數N(N<=50000)和巧克力的數量M(N<=M<=100000)。

輸出描述:
輸出一個數表示小Q第一天最多能喫多少塊巧克力。

輸入例子1:
3 7

輸出例子1:
4

#include <iostream>
#include <cmath>
using namespace std;

int fun(int n, int m){
	int start = ceil(m / 2.0);
	for (int i = start; i >= 1; i--){
		int t = 0;
		int ti = i;
		for (int j = 0; j < n; j++){
			t += ti;
			if (ti != 1)
				ti = ceil(ti / 2.0);
		}
		if (t <= m)
			return i;
	}
	return 0;
}

int main(){
	int n, m;
	cin >> n >> m;

	if (n == 1)
		cout << m << endl;
	else
		cout << fun(n, m) << endl;
	return 0;
}

4、小Q的歌單

小Q有X首長度爲A的不同的歌和Y首長度爲B的不同的歌,現在小Q想用這些歌組成一個總長度正好爲K的歌單,每首歌最多隻能在歌單中出現一次,在不考慮歌單內歌曲的先後順序的情況下,請問有多少種組成歌單的方法。

輸入描述:
每個輸入包含一個測試用例。
每個測試用例的第一行包含一個整數,表示歌單的總長度K(1<=K<=1000)。
接下來的一行包含四個正整數,分別表示歌的第一種長度A(A<=10)和數量X(X<=100)以及歌的第二種長度B(B<=10)和數量Y(Y<=100)。保證A不等於B。

輸出描述:
輸出一個整數,表示組成歌單的方法取模。因爲答案可能會很大,輸出對1000000007取模的結果。

輸入例子1:
5
2 3 3 3

輸出例子1:
9

#include <iostream>
#include <vector>
using namespace std;

// n選k組合數C(n,k) = C(n-1,k) + C(n-1,k-1)
void CreatSelect(vector<vector<long long>> &arr){
	arr[0][0] = 1;
	for (int i = 1; i <= 100; i++){
		arr[i][0] = 1;
		for (int j = 1; j <= 100; j++){
			arr[i][j] = (arr[i - 1][j] + arr[i - 1][j - 1] )% 1000000007;
		}
	}
}

long long fun(int k, int a, int x, int b, int y, vector<vector<long long>> arr){
	long long res = 0;
	for (int i = 0; i <= k / a && i <= x; i++){
		if ((k - a*i) % b == 0 && (k - a*i) / b <= y){
			// x裏選i個a,y裏選(k - a*i) / b個b
			res = (res + arr[x][i] * arr[y][(k - a*i) / b] % 1000000007) % 1000000007;
		}
	}
	return res;
}

int main(){
	int k;
	cin >> k;
	int a, b, x, y;
	cin >> a >> x >> b >> y;

	vector<vector<long long>> arr(101, vector<long long>(101));
	CreatSelect(arr);

	cout << fun(k, a, x, b, y, arr)  << endl;

	return 0;
}

5、安排機器

小Q的公司最近接到m個任務, 第i個任務需要xi的時間去完成, 難度等級爲yi。
小Q擁有n臺機器, 每臺機器最長工作時間zi, 機器等級wi。
對於一個任務,它只能交由一臺機器來完成, 如果安排給它的機器的最長工作時間小於任務需要的時間, 則不能完成,如果完成這個任務將獲得200 * xi + 3 * yi收益。

對於一臺機器,它一天只能完成一個任務, 如果它的機器等級小於安排給它的任務難度等級, 則不能完成。

小Q想在今天儘可能的去完成任務, 即完成的任務數量最大。如果有多種安排方案,小Q還想找到收益最大的那個方案。小Q需要你來幫助他計算一下。

輸入描述:
輸入包括N + M + 1行,
輸入的第一行爲兩個正整數n和m(1 <= n, m <= 100000), 表示機器的數量和任務的數量。
接下來n行,每行兩個整數zi和wi(0 < zi < 1000, 0 <= wi <= 100), 表示每臺機器的最大工作時間和機器等級。
接下來的m行,每行兩個整數xi和yi(0 < xi < 1000, 0 <= yi<= 100), 表示每個任務需要的完成時間和任務的難度等級。

輸出描述:
輸出兩個整數, 分別表示最大能完成的任務數量和獲取的收益。

輸入例子1:
1 2
100 3
100 2
100 1

輸出例子1:
1 20006

#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;

struct  Node {
	int time, grade;
};

bool Cmp(const Node &a, const Node &b) {
	if (a.time == b.time)
		return a.grade > b.grade;
	return a.time > b.time;
}

// case通過率爲90.00%,超時
int main() {
	int n, m; //機器的數量和任務的數量 1 <= n, m <= 100000
	cin >> n >> m;
	vector<Node> machine(n);
	vector<Node> task(m);
	for (int i = 0; i < n; i++){
		cin >> machine[i].time >> machine[i].grade;
	}
	for (int i = 0; i < m; i++){
		cin >> task[i].time >> task[i].grade;
	}

	sort(machine.begin(), machine.end(), Cmp);
	sort(task.begin(), task.end(), Cmp);

	int res = 0, value = 0;

	bool* flag = new bool[n];
	memset(flag, true, n);
	for (int i = 0; i < m; i++){
		int min_grade = 101;
		int min_j;
		for (int j = 0; j < n; j++){
			if (flag[j]){
				if (task[i].time <= machine[j].time){
					if (task[i].grade <= machine[j].grade && machine[j].grade < min_grade){
						min_grade = machine[j].grade;
						min_j = j;
					}
				}
				else{
					break;
				}
			}
		}
		if (min_grade != 101){
			res++;
			value += 200 * task[i].time + 3 * task[i].grade;
			flag[min_j] = false;
		}
	}

	delete[] flag;

	cout << res << " " << value << endl;

	return 0;
}

6、畫家小Q

畫家小Q又開始他的藝術創作。小Q拿出了一塊有NxM像素格的畫板, 畫板初始狀態是空白的,用’X’表示。
小Q有他獨特的繪畫技巧,每次小Q會選擇一條斜線, 如果斜線的方向形如’/’,即斜率爲1,小Q會選擇這條斜線中的一段格子,都塗畫爲藍色,用’B’表示;如果對角線的方向形如’’,即斜率爲-1,小Q會選擇這條斜線中的一段格子,都塗畫爲黃色,用’Y’表示。
如果一個格子既被藍色塗畫過又被黃色塗畫過,那麼這個格子就會變成綠色,用’G’表示。
小Q已經有想畫出的作品的樣子, 請你幫他計算一下他最少需要多少次操作完成這幅畫。

輸入描述:
每個輸入包含一個測試用例。
每個測試用例的第一行包含兩個正整數N和M(1 <= N, M <= 50), 表示畫板的長寬。
接下來的N行包含N個長度爲M的字符串, 其中包含字符’B’,‘Y’,‘G’,‘X’,分別表示藍色,黃色,綠色,空白。整個表示小Q要完成的作品。

輸出描述:
輸出一個正整數, 表示小Q最少需要多少次操作完成繪畫。

輸入例子1:
4 4
YXXB
XYGX
XBYY
BXXY

輸出例子1:
3

例子說明1:
XXXX
XXXX
XXXX
XXXX
->
YXXX
XYXX
XXYX
XXXY
->
YXXB
XYBX
XBYX
BXXY
->
YXXB
XYGX
XBYY
BXXY

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int n, m; //N和M(1 <= N, M <= 50), 表示畫板的長寬
vector<vector<char>> arr;

void fun_b(int i, int j){
	if (i >= 0 && i < n && j >= 0 && j < m && (arr[i][j] == 'B' || arr[i][j] == 'G')){
		if (arr[i][j] == 'B') 
			arr[i][j] = 'X';
		else 
			arr[i][j] = 'Y';
		fun_b(i - 1,j + 1);
		fun_b(i + 1, j - 1);
	}
	return;
}

void fun_y(int i, int j){
	if (i >= 0 && i < n && j >= 0 && j < m && (arr[i][j] == 'Y' || arr[i][j] == 'G')){
		if (arr[i][j] == 'Y') 
			arr[i][j] = 'X';
		else 
			arr[i][j] = 'B';
		fun_y(i + 1, j + 1);
		fun_y(i - 1, j - 1);
	}
	return;
}

/*
YXXB
XYGX
XBYY
BXXY
*/

int fun() {
	int res = 0;
	for (int i = 0; i < n; i++){
		for (int j = 0; j < m; j++){
			if (arr[i][j] == 'B'){
				fun_b(i, j);
				res++;
			}
			if (arr[i][j] == 'Y'){
				fun_y(i, j);
				res++;
			}
			if (arr[i][j] == 'G'){
				fun_b(i, j);
				fun_y(i, j);
				res += 2;
			}
		}
	}
	return res;
}

int main() {
	cin >> n >> m; 
	arr = vector<vector<char>> (n, vector<char>(m));
	string str;
	for (int i = 0; i < n; i++){
		cin >> str;
		for (int j = 0; j < m; j++){
			arr[i][j] = str[j];
		}
	}
	 
	cout << fun() << endl;

	return 0;
}

騰訊2017秋招筆試編程題

1、編碼

假定一種編碼的編碼範圍是a ~ y的25個字母,從1位到4位的編碼,如果我們把該編碼按字典序排序,形成一個數組如下: a, aa, aaa, aaaa, aaab, aaac, … …, b, ba, baa, baaa, baab, baac … …, yyyw, yyyx, yyyy 其中a的Index爲0,aa的Index爲1,aaa的Index爲2,以此類推。 編寫一個函數,輸入是任意一個編碼,輸出這個編碼對應的Index.

輸入描述:
輸入一個待編碼的字符串,字符串長度小於等於100.

輸出描述:
輸出這個編碼的index

輸入例子1:
baca

輸出例子1:
16331

#include <iostream>
#include <vector>
#include <string>

using namespace std;

vector<int> loop = { 0, 1, 26, 651, 16276 };

int fun(string str) {
	int res = 0, len = str.size();
	for (int i = 0; i < len; i++){
		res += (str[i] - 'a')*loop[4 -i]+1;
	}
	return res-1;
}

int main() {
	string str;
	
	while (cin >> str){
		cout << fun(str) << endl;
	}
	return 0;
}

2、遊戲任務標記

遊戲裏面有很多各式各樣的任務,其中有一種任務玩家只能做一次,這類任務一共有1024個,任務ID範圍[1,1024]。請用32個unsigned int類型來記錄着1024個任務是否已經完成。初始狀態都是未完成。 輸入兩個參數,都是任務ID,需要設置第一個ID的任務爲已經完成;並檢查第二個ID的任務是否已經完成。 輸出一個參數,如果第二個ID的任務已經完成輸出1,如果未完成輸出0。如果第一或第二個ID不在[1,1024]範圍,則輸出-1。

輸入描述:
輸入包括一行,兩個整數表示人物ID.

輸出描述:
輸出是否完成

輸入例子1:
1024 1024

輸出例子1:
1

#include <iostream>

using namespace std;

unsigned int flag[32];

// unsigned int爲32位,32個unsigned int爲32*32=1024
int fun(int n, int m) {
	// Index(N) = N / 32 = N >> 5;
	// Position(N) = N % 32 = N & 31; (對於2的冪的數才能)
	int index, position;
	index = (n - 1) >> 5;
	position = (n-1) & 31;
	flag[index] |= 1 << position;
	if (m >= 1 && m <= 1024){
		index = (m - 1) >> 5;
		position = (m - 1) & 31;
		return (flag[index]&(1<<position))!=0;
	}
	return -1;
}

int main() {
	int n,m;
	cin >> n >> m;

	cout << fun(n, m) << endl;
	return 0;
}

3、素數對

給定一個正整數,編寫程序計算有多少對質數的和等於輸入的這個正整數,並輸出結果。輸入值小於1000。
如,輸入爲10, 程序應該輸出結果爲2。(共有兩對質數的和爲10,分別爲(5,5),(3,7))

輸入描述:
輸入包括一個整數n,(3 ≤ n < 1000)

輸出描述:
輸出對數

輸入例子1:
10

輸出例子1:
2

#include <iostream>

using namespace std;

// 質數:只能被1和本身整除,最小質數爲2
bool is_zhishu(int x) {
	for (int i = 2; i*i <= x; i++){
		if (x%i == 0)
			return false;
	}
	return true;
}

int fun(int n) {
	int res = 0;
	for (int i = 2; i <= n / 2; i++){
		if (is_zhishu(i) && is_zhishu(n - i))
			res++;
	}
	return res;
}

int main() {
	int n;
	cin >> n;

	cout << fun(n) << endl;
	return 0;
}

4、geohash編碼

geohash編碼:geohash常用於將二維的經緯度轉換爲字符串,分爲兩步:第一步是經緯度的二進制編碼,第二步是base32轉碼。
此題考察緯度的二進制編碼:算法對緯度[-90, 90]通過二分法進行無限逼近(取決於所需精度,本題精度爲6)。注意,本題進行二分法逼近過程中只採用向下取整來進行二分,針對二分中間值屬於右區間。算法舉例如下: 針對緯度爲80進行二進制編碼過程:

  1. 區間[-90, 90]進行二分爲[-90, 0),[0, 90],成爲左右區間,可以確定80爲右區間,標記爲1;
  2. 針對上一步的右區間[0, 90]進行二分爲[0, 45),[45, 90],可以確定80是右區間,標記爲1;
  3. 針對[45, 90]進行二分爲[45, 67),[67,90],可以確定80爲右區間,標記爲1;
  4. 針對[67,90]進行二分爲[67, 78),[78,90],可以確定80爲右區間,標記爲1;
  5. 針對[78, 90]進行二分爲[78, 84),[84, 90],可以確定80爲左區間,標記爲0;
  6. 針對[78, 84)進行二分爲[78, 81), [81, 84),可以確定80爲左區間,標記爲0;

輸入描述:
輸入包括一個整數n,(-90 ≤ n ≤ 90)

輸出描述:
輸出二進制編碼

輸入例子1:
80

輸出例子1:
111100

#include <iostream>
#include <string>
#include <cmath>

using namespace std;

// -66
string fun(int n) {
	string res;
	int k = 0;
	int l = -90, r = 90;
	while (k != 6){
		int mid = floor((l + r) / 2.0);
		if (mid <= n){
			res.push_back('1');
			l = mid;
		}
		else{
			res.push_back('0');
			r = mid;
		}
		k++;
	}
	return res;
}

string fun2(int n) {
	string res;
	int k = 0;
	int l = -90, r = 90;
	while (k != 6){
		int mid = l + r > 0 ? floor((l + r) / 2.0) : -floor(-(l + r) / 2.0);
		if (mid <= n){
			res.push_back('1');
			l = mid;
		}
		else{
			res.push_back('0');
			r = mid;
		}
		k++;
	}
	return res;
}

int main() {
	int n; // (-90 ≤ n ≤ 90)
	cin >> n;

	cout << fun2(n) << endl;
	return 0;
}

注:題中向下取整存在歧義

騰訊2017暑期實習生編程題

1、構造迴文

給定一個字符串s,你可以從中刪除一些字符,使得剩下的串是一個迴文串。如何刪除才能使得迴文串最長呢?
輸出需要刪除的字符個數。

輸入描述:

輸入數據有多組,每組包含一個字符串s,且保證:1<=s.length<=1000.

輸出描述:

對於每組數據,輸出一個整數,代表最少需要刪除的字符個數。

輸入例子1:
abcda
google

輸出例子1:
2
2

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

// 求原字符串和其反串的最大公共子序列的長度
int fun(string s1, string s2) {
	if (s1.size() == 1) return 1;
	int len = s1.size();
	vector<vector<int>> arr(len + 1, vector<int>(len + 1));
	for (int i = 0; i <= len; i++){
		for (int j = 0; j <= len; j++){
			if (i == 0 || j == 0){
				arr[i][j] =0;
			}
			else if (s1[i-1] == s2[j-1]){
				arr[i][j] = arr[i - 1][j - 1] + 1;
			}
			else{
				arr[i][j] = max(arr[i][j - 1], arr[i-1][j]);
			}
		}
	}
	return arr[len][len];
}

int main() {
	string s; // 1 <= s.length <= 1000
	while (cin >> s){
		string s2 = s;
		reverse(s2.begin(), s2.end());
		cout << s.size()-fun(s,s2) << endl;
	}

	return 0;
}

2、算法基礎-字符移位

小Q最近遇到了一個難題:把一個字符串的大寫字母放到字符串的後面,各個字符的相對位置不變,且不能申請額外的空間。
你能幫幫小Q嗎?

輸入描述:

輸入數據有多組,每組包含一個字符串s,且保證:1<=s.length<=1000.

輸出描述:

對於每組數據,輸出移位後的字符串。

輸入例子1:
AkleBiCeilD

輸出例子1:
kleieilABCD

#include <iostream>
#include <string>

using namespace std;

bool is_upper(char c){
	return c >= 'A' && c <= 'Z';
}

string fun(string &s) {
	if (s.size() == 1) return s;
	for (int i = 0; i < s.size(); i++){
		if (is_upper(s[i])){
			for (int j = i + 1; j < s.size(); j++){
				if (!is_upper(s[j])){
					int  k = j;
					char t = s[j];
					while (k>i){
						s[k] = s[k - 1];
						k--;
					}
					s[i] = t;
					break;
				}
			}
		}
	}
	return s;
}

int main() {
	string s; // 1 <= s.length <= 1000

	while (cin >> s){
		cout << fun(s) << endl;
	}

	return 0;
}

3、有趣的數字

小Q今天在上廁所時想到了這個問題:有n個數,兩兩組成二元組,相差最小的有多少對呢?相差最大呢?

輸入描述:

輸入包含多組測試數據。
對於每組測試數據:
N - 本組測試數據有n個數
a1,a2…an - 需要計算的數據
保證:
1<=N<=100000,0<=ai<=INT_MAX.

輸出描述:

對於每組數據,輸出兩個數,第一個數表示差最小的對數,第二個數表示差最大的對數。

輸入例子1:
6
45 12 45 32 5 6

輸出例子1:
1 2

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

void fun(int n,vector<int> &vec) {
	int min_count = 0, max_count = 0;
	if (n > 1){
		sort(vec.begin(), vec.end());
		if (vec[0] == vec[n - 1]){ // 11111
			min_count = n*(n - 1) / 2;
			max_count = n*(n - 1) / 2;
		}
		else{
			// min
			int min = vec[1] - vec[0];
			for (int i = 0; i < n - 1; i++){
				if (vec[i + 1] - vec[i] < min){
					min = vec[i + 1] - vec[i];
				}
			}
			if (min == 0){ // 11233
				int time;
				for (int i = 0; i < n; i++){
					time = 1;
					while (i + 1 < n && vec[i + 1] == vec[i]){
						time++;
						i++;
					}
					min_count += time*(time - 1)/2;
				}
			}
			else{ // 12457
				for (int i = 0; i < n - 1; i++){
					if (vec[i + 1] - vec[i] == min){
						min_count++;
					}
				}
			}

			// max
			int max = vec[n - 1] - vec[0];
			int l = 0, r = 0;
			for (int i = 0; i < n; i++){
				if (vec[i] == vec[0]) l++;
				else break;
			}
			for (int i = n - 1; i >= 0; i--){
				if (vec[i] == vec[n-1]) r++;
				else break;
			}
			max_count = l*r;
		}
	}
	cout << min_count << " " << max_count << endl;
}

int main() {
	int n;
	while (cin >> n){
		vector<int> vec(n);
		for (int i = 0; i < n; i++){
			cin >> vec[i];
		}
		fun(n, vec);
	}
	
	return 0;
}

騰訊2016研發工程師編程題

1、生成格雷碼

在一組數的編碼中,若任意兩個相鄰的代碼只有一位二進制數不同, 則稱這種編碼爲格雷碼(Gray Code),請編寫一個函數,使用遞歸的方法生成N位的格雷碼。

給定一個整數n,請返回n位的格雷碼,順序爲從0開始。

測試樣例:
1
返回:[“0”,“1”]

/*n: 0   1    2     3
     0   0   00   000
	     1   10   100
			      110
		      11  010
              01
				  011
				  111
				  101
				  001
*/
class GrayCode {
public:
	// 題目不嚴謹case通過率爲9.09% 
	// 用例:2
	// 對應輸出應該爲:["00","01","11","10"]
	// 你的輸出爲:["00","10","11","01"]
    vector<string> getGray2(int n) {
        if (n == 0) return{ "0" };
        vector<string> res{ "0", "1" };
        for (int i = 1; i < n; i++){
            for (int j = 0; j < res.size(); j++){
                res[j].push_back('0');
            }
            for (int j = res.size()-1; j >=0; j--){
                string t = res[j];
                t[t.size() - 1] = '1';
                res.push_back(t);
            }
        }
        return res;
    }
	vector<string> getGray(int n) {
        if (n == 0) return{ "0" };
        vector<string> res{ "0", "1" };
        for (int i = 1; i < n; i++){
            for (int j = 0; j < res.size(); j++){
                res[j]='0' + res[j];
            }
            for (int j = res.size()-1; j >=0; j--){
                string t = res[j];
                t[0] = '1';
                res.push_back(t);
            }
        }
        return res;
    }
};

2、微信紅包

春節期間小明使用微信收到很多個紅包,非常開心。在查看領取紅包記錄時發現,某個紅包金額出現的次數超過了紅包總數的一半。請幫小明找到該紅包金額。寫出具體算法思路和代碼實現,要求算法儘可能高效。

給定一個紅包的金額數組gifts及它的大小n,請返回所求紅包的金額。

若沒有金額超過總數的一半,返回0。
測試樣例:
[1,2,3,2,2],5
返回:2

class Gift {
public:
    /*
     如果重複的次數超過一半的話,一定有相鄰的數字相同這種情況的
     對數組同時去掉兩個不同的數字,到最後剩下的一個數就是該數字
    */
    int getValue(vector<int> gifts, int n) {
        int res = gifts[0], time = 1;
        for(int i=1;i<gifts.size();i++){
            if(gifts[i]==res) time++;
            else{
                time--;
                if(time == 0){
                    res = gifts[i];
                }
            }
        }
        time = 0;
        for(int i=0;i<gifts.size();i++){
            if(gifts[i] == res) time++;
        }
        return time>gifts.size()/2?res:0;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章