class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
if(numbers.size()==0)
return 0;
int num=1;
int tag=numbers[0];
int i=1;
while(i<numbers.size()){
if(tag!=numbers[i]){
num--;
}
else{
num++;
}
if(num==0){
tag=numbers[i];
num=1;
}
i++;
}
num=0;
i=0;
while(i<numbers.size()){
if(numbers[i]==tag)
num++;
if(num>(numbers.size()/2))
return tag;
i++;
}
return 0;
}
};
解题思路:
用类似快排的二分 思想,将第k个位置的数据找到,他之前都小于等于自己,之后大于等于自己
然后将0--k-1的数据保存返回
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> vec;
int size = input.size();
if (size == 0 || k>size || k<1)//参数检测
return vec;
//第一次递归 找参照位置
int index = partition(input, size, 0, size - 1);
while (index != k-1 ){//持续递归知道找到 确切 k 位置的值
if (index>k-1 ){
index = partition(input, size, 0, index-1);
}
else if (index<k-1 ){
index = partition(input, size, index+1, size-1);
}
}
int i = 0;
while (i<=index){//保存数据
vec.push_back(input[i]);
i++;
}
return vec;
}
//{4, 5, 1, 6, 2, 7, 3, 8};
int partition(vector<int>& input, int size, int head, int end){
int mid = (head>>1) + (end>>1);
int key = input[(head>>1) + (end>>1)];
int index = head;
while (head <end){//类似头尾 快排 法的找位置
if (input[head]>key){
if (input[end]<=key&&end!=mid){
swap(input[head], input[end]);
}
--end;
}
else
++head;
}
if (key>=input[end]&&mid<end){//交换key值,与结束位置
swap(input[end], input[mid]);
}
if (key < input[end] && mid>end){
swap(input[end], input[mid]);
}
return head;
}
};
解题思路:考虑清楚情况 遍历一遍即可
1.全负,结果是最大负数,有0 为零;
2.全正,结果为所有和
3.有正有负,<1.保存判断被负数阻断的每部分和
< 2.如果加上这个负数结果为正继续加;为负,判断该和与每部分正数最大和那个大,保存最大,继续循环
<3.如果最后一个数为负结束循环,否则加上
<4.做 <2.的大大小判断
class Solution {
public:
int FindGreatestSumOfSubArray(vector<int> array) {
if (array.size() == 0)
return 0;
return findMaxSum(array);
}
private:
int findMaxSum(vector<int> array)
{
int sum = 0;//保存每部分正数和
int prevSum = 0;//保存大于0的和
int maxSum = 0;//保存每部分最大和
int i = 0;//循环数组下标
int brk= 0;//是否为负数,中断sum的加
int maxSmall = 0;//最大负数
int j = 0;//判断书否全负
//[1,-2,3,10,-4,7,2,-5]
//{6,-3,-2,7,-15,1,2,2}
while (i<array.size()){
if (i == array.size() - 1 && array[i]<0)
break;
if (array[i] >= 0)
j = 1;
if (array[i]>0 && brk == 0){
prevSum += array[i];
}
else{
if (maxSmall == 0)
maxSmall=array[i];
else if (maxSmall<array[i])
maxSmall = array[i];
brk = 1;
}
if (sum + array[i] > 0){
sum +=array[i];
}
else{
int tmp = sum > prevSum ? sum : prevSum;
maxSum = tmp > maxSum ? tmp : maxSum;
sum = 0;
prevSum = 0;
brk = 0;
}
i++;
}
int tmp = sum > prevSum ? sum : prevSum;
maxSum = tmp > maxSum ? tmp : maxSum;
if (j == 0)
return maxSmall;
return maxSum;
}
};
int find_num(vector<int> arr){//最简方法
if (arr.size() <= 0){
return 0;
}
int max = 0x80000000;
int cur = 0;
int i = 0;
while (i < arr.size()){
if (cur <= 0)
cur = arr[i];
else
cur += arr[i];
if (cur>max)
max = cur;
++i;
}
return max;
}
解题思路:很普遍的题,要想脱颖而出,必须将效率最大化。
分析:1.遍历 1--n 挨个数1的方法,缺陷是先遍历过得数字,在后面进位后还得遍历。
2.每次对每个数的每一位判断,也需要进行循环。
要想优化 问题,要从解决以上缺陷下手
优化思路:1、用递归的思路可以把之前遍历的数据复用。例132 拆分为
100 和 32 ,从1--132 便利中 1-- 32 已经统计过 可以复用。直接在计算1-99
即可
2.省去循环判断每个数的1 改为复用从1 开始每一位的 1的个数。
例如: 1-9 只有一个1,20中,经历 2 次1-9 的累加。则 有 2个1 , 又因为有1x,始终有1,那么1- 20 含1 的个数为 1*2+1*10=12;
class Solution {
public:
int NumberOf1Between1AndN_Solution(int n)
{
if (n <= 0)
return 0;
return numOfOne(n);
}
private:
int numOfOne(int n){
if (n == 0)
return 0;//递归 到0,返回0
if (n < 10)//1-9 返回1
return 1;
int tmp = n;//临时存储 n
int i = 1;//循环变量 || 几位数
int bit = 1;//计算是最小的 几位数 比如:3位数 100
int numOfBit = 0;//最高位权值
int ret = 0,ret1=0;//拆分后 分别的返回值
while (n / 10>0){//得到n的最高位数 并统计为几位数
n /= 10;
++i;
}
numOfBit = n;
while (i>1){ //得到最高位权值乘位数,和最小的几位数
n *= 10;
bit *= 10;
i--;
}
ret = numOfOne(tmp-n);//递归 最高位剩余部分
ret1 += numOfBit*numOfOne(bit-1);//递归1--最小的n位数-1
if (numOfBit > 1)
ret += n / numOfBit;
if (numOfBit == 1)
ret += tmp - n+1;
ret += ret1;//计算总数
return ret;
}
};
解题思路:
本题的重点是确定一组数字中每个数最高位 依次最小的数,存入字符串。将此功能的实现思路总结如下:
1.将所有数字 转换为字符串 存入数组。
2.从每个数最高位即 str[0]开始比较最小。如果全相等,比较次高位。
3.如果字符串长度不一。则长的那个字符串 次高位,也要比短的字符串最低位小。否者 短的字符串比较大。例如:321 、32 则定义321<32 ,因为32132 <32321
4.存在0 则我们规定0可以为最高位。例如:0、123 则1230>0123
class Solution {
public:
string PrintMinNumber(vector<int> numbers) {
if (numbers.size() == 0)
return "";
vector<string> str;
string ret;
int i = 0;
while (i<numbers.size()){
char buf[11];
sprintf(buf, "%d", numbers[i]);
string tmp(buf);
str.push_back(tmp);
i++;
}
while (!str.empty()){
i = smallNum(str);
ret += str[i];
str.erase(str.begin() + i);
}
return ret;
}
private:
int smallNum(vector<string> str){
if (str.size() == 1)
return 0;
int i = 1, j = 0;
int k=0;
int small = 0;
while (i<str.size() ){
while (1){
if (j<str[small].size() && j<str[i].size()){
if (str[i][j]<str[small][j]){
small = i;
break;
}
k = j;
j++;
}
else{
if (j<str[small].size()){
if (str[small][j]>str[i][k]){
small = i;
break;
}
j++;
}
else if (j < str[i].size()){
if (str[i][j] < str[small][k]){
small = i;
break;
}
j++;
}
else
break;
}
}
i++;
j = 0;
}
return small;
}
};
分析:一般方法:将1 到 第 index个丑数 依次求因子,判断是不是丑数
缺点:时间复杂度太高
高性能方法:每个丑数 都是由比他小的某个丑数 *2 或 *3 或 *5得到的。
只要能确定顺序 ,就可高效的解决该问题
class Solution {
public:
int GetUglyNumber_Solution(int index) {
if(index<=0)
return 0;
int *arry=new int[index];
int min=1;
arry[0]=1;
int next_index=1;
int min2=0;
int min3=0;
int min5=0;
while(next_index<index){
min=min_ugly_num(arry[min2]*2,arry[min3]*3,arry[min5]*5);
arry[next_index]=min;
while(arry[min2]*2<=min)
min2++;
while(arry[min3]*3<=min)
min3++;
while(arry[min5]*5<=min)
min5++;
++next_index;
}
min=arry[next_index-1];
delete[] arry;
return min;
}
int min_ugly_num(int i,int j, int k){
int min=i<j?i:j;
min=min<k?min:k;
return min;
}
};
分析:用哈希标的方法 以空间换时间 可高效解决
class Solution {
public:
int FirstNotRepeatingChar(string str) {
if(str.size()==0)
return -1;
int hash[256]={0};
int i=0;
while(i<str.size()){
hash[str[i++]]++;
}
i=0;
while(i<str.size()){
if(hash[str[i]]==1)
return i;
++i;
}
return -1;
}
};
转载于:https://blog.51cto.com/shaungqiran/1784746