数组中出现次数超过一半的数字,最小的k个数,连续子数组的最大和,整数中1出现的次数(剑指offer28-31)c++版本

#include <iostream>
#include <vector>

using namespace std;

class Solution {
public:	
	//JZ28 数组中出现次数超过一半的数字
	int MAX = 0;
	int MoreThanHalfNum_Solution(vector<int> numbers);
	bool ismorenum(vector<int> numbers, int len, int result);
	//JZ29 最小的k个数
	vector<int> GetLeastNumbers_Solution(vector<int> input, int k);
	int partition(vector<int> &input, int begin, int end);
	//JZ30 连续子数组的最大和
	int MAX_30 = 0;
	int FindGreatestSumOfSubArray(vector<int> array);
	int sumofith(vector<int> array, int i, int &result);
	//JZ31 整数中1出现的次数
	int NumberOf1Between1AndN_Solution(int n);
	int subnumber(int n, int count);
};

//JZ28
int Solution::MoreThanHalfNum_Solution(vector<int> numbers) {
	//直观解法,排序,超过一半的数必定位于中间。
	//超过一半的数出现的次数必定超过其余全部数出现次数的总和。假设存在这样的数,先找到此数,再判断是否知足条件。
	if (numbers.empty()) {
		MAX = -1;
		return 0;
	}
	int len = numbers.size();
	int num = 1;
	int result = numbers[0];
	for (int i = 1; i < len; i++) {
		if (num == 0) {
			result = numbers[i];
			num = 1;
		}
		else if (numbers[i] == result)
			num++;
		else
		{
			num--;
		}		
	}
	if (ismorenum(numbers, len, result))	return result;
	else {
		MAX = -2;
		return 0;
	}
}
bool Solution::ismorenum(vector<int> numbers, int len, int result) {
	int num = 0;
	for (vector<int>::iterator it = numbers.begin(); it != numbers.end(); it++)
		if (*it == result)	num++;
	if (num > (len >> 1))	return true;
	return false;
}
//JZ29
vector<int> Solution::GetLeastNumbers_Solution(vector<int> input, int k) {
	//解法1.维持一个宽度为K的set容器
	//解法2.利用快排的思想
	if (input.empty())	return vector<int>();
	int len = input.size();
	if (len < k || k <= 0)	return vector<int>();
	int begin = 0, end = len - 1;
	int index = partition(input, begin, end);
	while (index != k-1) {
		if (index > k-1) {
			end = index - 1;
			index = partition(input, begin, end);
		}
		else {
			begin = index + 1;
			index = partition(input, begin, end);
		}
	}
	vector<int> result;
	for (int i = 0; i < k; i++)
		result.push_back(input[i]);
	return result;
}
int Solution::partition(vector<int> &input, int begin, int end) {
	//返回基数所在的位置
	int base = input[begin];
	while (begin < end) {
		while(begin < end && input[end] >= base)
			end--;
		if (begin < end)
			input[begin++] = input[end];
		while (begin < end && input[begin] <= base)
			begin++;
		if (begin < end)
			input[end--] = input[begin];
	}
	input[begin] = base;
	return begin;
}
//JZ30 连续子数组的最大和
int Solution::FindGreatestSumOfSubArray(vector<int> array) {
	//f(i)表示以第i个元素结尾的最大连续子数组,则,if f(i-1)>0, f(i)=f(i-1)+a(i); else f(i)=a(i)。
	if (array.empty()) {
		MAX_30 = -1;
		return 0;
	}
	int len = array.size();
	int result = array[0];
	int temp = sumofith(array, len - 1, result);
	return result;
}
int Solution::sumofith(vector<int> array, int i, int &result) {
	if (i == 0)	return array[0];
	int sumofiminus1 = sumofith(array, i - 1, result);
	int temp = 0;
	if (sumofiminus1 > 0) {
		temp = sumofiminus1 + array[i];
	}
	else
	{
		temp = array[i];
	}
	result = result > temp ? result : temp;
	return temp;
}
//JZ31 整数中1出现的次数
int Solution::NumberOf1Between1AndN_Solution(int n) {
	if (n < 1)	return 0;
	int nums = 0;
	int count = 0;//用来记录n的位数
	int temp = n;
	while (temp) {
		count++;
		temp /= 10;
	}
	nums += subnumber(n, count);
	return nums;
}
int Solution::subnumber(int n, int count) {
	if (count <= 1) {
		if (n >= 1)	return 1;
		else
		{
			return 0;
		}
	}
	int result = 0;
	int temp = pow(10, count - 1);
	int topdigit = n / temp;//记录最高位
	int n_temp = n - temp;
	if (topdigit == 1) {
		result += n_temp + 1 + topdigit * (count - 1) * (temp / 10);
	}
	else if (topdigit == 0);//注意遇到0的处理
	else {
		result += temp + topdigit * (count - 1) * (temp / 10);
	}
	result += subnumber(n - topdigit * temp, --count);
	return result;
}

//JZ28
void test1(){
	vector<int> temp = {1,2,3,3,3,4,5,4,3,3,3};
	Solution s;
	cout << s.MoreThanHalfNum_Solution(temp) << endl;
	cout << s.MAX;
	return;
}
//JZ29
void test2() {
	vector<int> temp = { 4, 5, 1, 6, 2, 7, 3, 8 };
	int k = 4;
	Solution s;
	vector<int> result = s.GetLeastNumbers_Solution(temp, k);
	for (vector<int>::iterator it = result.begin(); it != result.end(); it++)
		cout << *it << ' ';
	return;
}
//JZ30
void test3() {
	vector<int> temp = { 6,-3,-2,7,-15,1,2,2 };
	Solution s;
	cout << s.FindGreatestSumOfSubArray(temp);
	return;
}
//JZ31
void test4() {
	Solution s;
	cout << s.NumberOf1Between1AndN_Solution(100);
	return;
}

int main() {
	//test1();
	//test2();
	//test3();
	test4();
	system("pause");
	return 0;
}