# 剑指offer（一）数组

## 面试题3：二维数组中的查找

    bool Find(int target, vector<vector<int> > array) {
bool find = false;
int rows = array.size();
int columns = array[0].size();
if(rows>0 && columns>0){
int row = 0;
int column = columns-1;
while(row<rows && column>=0){
if(array[row][column] == target){
find = true;
break;
}else if(array[row][column] < target){
row++;
}else{
column--;
}
}
}
return find;
}

## 面试题8：旋转数组的最小数字

class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {
if(rotateArray.size()==0)
return 0;
int index1 = 0;
int index2 = rotateArray.size()-1;
int indexMid = index1;  //适于数组本身是排好序的
while(rotateArray[index1] >= rotateArray[index2]){
if(index2-index1==1){
indexMid = index2;
break;
}
indexMid = (index1+index2)/2;
if(rotateArray[index1]==rotateArray[index2] && rotateArray[index1]==rotateArray[indexMid])
return MinInOrder(rotateArray,index1,index2);
if(rotateArray[indexMid] >= rotateArray[index1])
index1 = indexMid;
if(rotateArray[indexMid] <= rotateArray[index2])
index2 = indexMid;
}
return rotateArray[indexMid];
}
int MinInOrder(vector<int> rotateArray, int index1, int index2){
int tmp = rotateArray[index1];
for(int i=index1+1; i<=index2; i++)
if(rotateArray[i] < tmp){
tmp = rotateArray[i];
break;
}
return tmp;
}
};

## 面试题14：调整数组顺序使奇数位于偶数前面

class Solution {
public:
void reOrderArray(vector<int> &array) {
if(array.size()==0)
return;
int left = 0;
int right = array.size()-1;
while(left < right){
while(left<right && (array[left]&0x1)!=0)
left++;
while(left<right && (array[right]&0x1)==0)
right--;
if(left < right){
int temp = array[left];
array[left] = array[right];
array[right] = temp;
}
}
}
};

class Solution {
public:
void reOrderArray(vector<int> &array) {
int len = array.size();
if(len==0)
return;
vector<int> res(len);
int p = 0;
int index = 0;
while(p < len){
if((array[p]&0x1)!=0)
res[index++] = array[p];
p++;
}
p = 0;
while(p < len){
if((array[p]&0x1)==0)
res[index++] = array[p];
p++;
}
array = res;
}
};

## 面试题29：

class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
if(numbers.size()==0)
return 0;
int count = 1;
int result = numbers[0];
for(int i=1;i<numbers.size();i++){
if(count == 0){
result = numbers[i];
count = 1;
}else{
if(result == numbers[i])
count++;
else
count--;
}
}
count = 0;
for(int i=0;i<numbers.size();i++){
if(result == numbers[i])
count++;
}
if(count*2 <= numbers.size())
result = 0;
return result;
}
};

## 面试题30：最小的K个数

class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> result;
if(k > input.size() || k < 1) //如果k比输入数组大小还要大，就返回[]
return result;
multiset<int,greater<int>> leastNums; //leastNums从大到小排序
vector<int>::iterator it = input.begin();
for(;it!=input.end();it++){
if(leastNums.size()<k)
leastNums.insert(*it);
else{
multiset<int,greater<int>>::iterator iter = leastNums.begin();
if(*it < *(leastNums.begin())){
leastNums.erase(*iter);
leastNums.insert(*it);
}
}
}
multiset<int,less<int>>::iterator iter = leastNums.begin();
for(;iter!=leastNums.end();iter++){
result.push_back(*iter);
}
return result;
}
};

## 面试题31：连续子数组的最大和

class Solution {
public:
int FindGreatestSumOfSubArray(vector<int> array) {
if(array.size()==0)
return 0;
int tmp = array[0];
int max = tmp;
for(int i=1;i<array.size();i++){
if(tmp <= 0)
tmp = array[i];
else
tmp += array[i];
if(tmp > max)
max = tmp;
}
return max;
}
};

## 面试题33：把数组排成最小的数

class Solution {
public:
string PrintMinNumber(vector<int> numbers) {
int len = numbers.size();
if(len == 0)
return "";
sort(numbers.begin(),numbers.end(),cmp);
string result;
for(int i=0;i<len;i++){
result += to_string(numbers[i]);
}
return result;
}
static bool cmp(int a, int b){
string ab = to_string(a) + to_string(b);
string ba = to_string(b) + to_string(a);
return ab < ba;
}
};

## 面试题36：

class Solution {
public:
int InversePairs(vector<int> data) {
if(data.size()==0)
return 0;
int len = data.size();
vector<int> copy = data;
return InversePairsCore(data,copy,0,len-1);
}
int InversePairsCore(vector<int> &data, vector<int> &copy, int start, int end){
if(start == end){
copy[start] = data[start];
return 0;
}
int mid = (start+end)/2;
long left = InversePairsCore(copy,data,start,mid);
long right = InversePairsCore(copy,data,mid+1,end);

long count = 0;
int i = mid;
int j = end;
int index = end;
while(i>=start && j>=mid+1){
if(data[i] > data[j]){
count += j - mid;
copy[index--] = data[i--];
}else{
copy[index--] = data[j--];
}
}
for(;i>=start;i--){
copy[index--] = data[i];
}
for(;j>=mid+1;j--){
copy[index--] = data[j];
}
return (left + right +count) % 1000000007;
}
};

# #

class Solution {
public:
int GetNumberOfK(vector<int> data ,int k) {
if(data.size()==0)
return 0;
return core(data,k,0,data.size()-1);
}
int core(vector<int> data ,int k, int start, int end){
if(start>end)
return 0;
int mid = (start+end)/2;
if(data[mid] < k)
return core(data,k,mid+1,end);
else if(data[mid] > k)
return core(data,k,start,mid-1);
else
return (1+core(data,k,mid+1,end)+core(data,k,start,mid-1));
}
};

## 面试题40：数组中只出现一次的数字

class Solution {
public:
void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
int len = data.size();
if(len<2)
return;
int tmp = 0;
for(int i=0;i<len;i++){
tmp ^= data[i];
}
unsigned int first1Index = findFirst1Index(tmp);
*num1 = *num2 = 0;
for(int i=0;i<len;i++){
if((data[i]>>first1Index) & 1 == 1){
*num1 ^= data[i];
}else{
*num2 ^= data[i];
}
}
}
unsigned int findFirst1Index(int tmp){
int index = 0;
while(((tmp & 1) == 0) && (index < 8 * sizeof(int))){ //总是通不过，原因为(tmp & 1)少了括号，==优先级比&高
tmp = tmp >> 1;
index++;
}
return index;
}
};

## 面试题52：构建乘积数组

class Solution {
public:
vector<int> multiply(const vector<int>& A) {
int n = A.size();
vector<int> B(n);
B[0] = 1;
for(int i=1;i<n;i++)
B[i] = B[i-1]*A[i-1];
double temp = 1;
for(int i=n-2;i>=0;i--){
temp *= A[i+1];
B[i] *= temp;
}
return B;
}
};