wKioL1dNWofzAG0fAAGb_hf682s218.png

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;
    }
};



wKioL1dNWofy1uXlAAEHLIJ_amU968.png


解题思路:

     用类似快排的二分 思想,将第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;
	}

};

wKiom1dNYuijE0maAAFubwXZqwE872.png


解题思路:考虑清楚情况  遍历一遍即可

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;
}

wKioL1dOYD-yH-FHAAF7xlFPI1w667.png

解题思路:很普遍的题,要想脱颖而出,必须将效率最大化。

    分析: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;
	}
};

wKioL1dP1LKT22geAAGJ6F_figM254.png

解题思路:

        本题的重点是确定一组数字中每个数最高位 依次最小的数,存入字符串。将此功能的实现思路总结如下:

        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;

	}
};


wKiom1dP0qfjBBkIAAFlVnCNtZY930.png

分析:一般方法:将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;
    }
};

wKioL1dnfeqw0Y4PAAEOTEK-iL4832.png

分析:用哈希标的方法 以空间换时间 可高效解决

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;
    }
};