第一题:二维数组中查找
class Solution {
public:
bool Find(int target, vector<vector<int> > array) {
//行
for(int i=0;i<array.size();i++)
{
//列
for(int j=0;j<array[0].size();j++)
{
if(array[i][j]==target)
{
return true;
}
}
}
return false;
}
};
class Solution {
public:
bool Find(int target, vector<vector<int> > array) {
//从左下角元素往上查找,右边元素是比这个元素大,
//上边是的元素比这个元素小。
//于是,target比这个元素小就往上找,比这个元素大就往右找。
//如果出了边界,则说明二维数组中不存在target元素。
int rows = array.size()-1;
int cols = array[0].size()-1;
int i=rows,j=0;
while(i>=0 && j<=cols)
{
if(array[i][j]==target)
return true;
else if(array[i][j]<target)
j++;
else
i--;
}
return false;
}
};
第二题:旋转数组的最小数字
//将vector中的数放入deque容器,通过deque中的sort函数进行排序,
//第一个就是最小数
class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {
if(rotateArray.size()==0) return 0;
return dfs(rotateArray);
}
int dfs(vector<int> array)
{
deque<int>q;
while(!array.empty())
{
q.push_back(array.back());
array.pop_back();
}
sort(q.begin(),q.end());
return q[0];
}
};
//二分法查找
class Solution {
public:
int minNumberInRotateArray(vector<int> nums) {
int n=nums.size()-1;
if(n<0) return -1;
//找到nums[0] 和 nums[n] 不相等的位置
//例如 [3,3,4,5,1,2,3,3]
while(n>0&&nums[n]==nums[0]) n--;
if(nums[n]>=nums[0]) return nums[0];
int l=0,r=n;
while(l<r)
{
// >> 右移操作 缩减二倍 加减运算符优先级 高于 位移运算符
int mid=l+r >> 1;
if(nums[mid]<nums[0]) r=mid;
else l=mid+1;
}
return nums[r];
}
};
第三题:调整数组顺序使奇数位于偶数前面
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param array int整型vector
* @return int整型vector
*/
vector<int> reOrderArray(vector<int>& array) {
// write code here
if(array.empty()) return array;
//i 为插入元素的位置
int i=0;
//j 为指针往后移动的次数
int j=0;
//for(vector<int>::iterator it=array.begin();it!=array.end();it++)
while(j<array.size())
{
//if(*it%2==1)
if(array[j]%2==1)
{
//int a=*it;
int a=array[j];
//删除 奇数位置的元素
array.erase(array.begin()+j);
//在前面插入奇数
array.insert(array.begin()+i,a);
i++;
}
j++;
}
return array;
}
};
第四题:数组中出现次数超过一半的数字
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
if(numbers.empty()) return 0;
int len = numbers.size();
int Max = numbers[0];
//找出数组中最大的数Max
for(int j=0;j<len;j++)
{
if(numbers[j]>Max)
Max=numbers[j];
}
//创建一个长度Max的数组arr
int arr[Max];
for(int i=0;i<Max;i++)
{
arr[i]=0;
}
//将原始数组中的每个数放入对应的arr下标位置,当相同数放入一个位置时,计数+1
int L=0;
while(L<len)
{
if(numbers[L])
{
arr[numbers[L]-1]++;
}
L++;
}
//检查每个位置的计数是否大于原始数组的一半,若存在,则输出下标
for(int h=0;h<Max;h++)
{
if(arr[h]>(len/2))
return h+1;
}
return 0;
}
};
第五题:连续子数租的最大和
class Solution {
public:
int FindGreatestSumOfSubArray(vector<int> array) {
if(array.empty()) return NULL;
int s=0;
int res=INT_MIN;
for(auto x:array)
{
if(s<=0) s=0;
s += x;
res = max(res,s);
}
return res;
}
};
第六题:把数组排成最小的数
class Solution {
public:
static bool cmp(int a, int b)
{
string as = to_string(a), bs = to_string(b);
return as + bs < bs + as;
}
string PrintMinNumber(vector<int> numbers) {
sort(numbers.begin(),numbers.end(),cmp);
string res;
for(auto x:numbers)
{
res += to_string(x);
}
return res;
}
};
第七题:数组中的逆序对
class Solution {
public:
int merge(vector<int> &nums, int l, int r)
{
//[ ]
//[ i mid][mid+1 j ]
//mid - i + 1
if(l >= r) return 0;
int mid = (l+r)>>1; //右移一位,表示除以2
int res = (merge(nums, l, mid) + merge(nums, mid+1, r)) % 1000000007;
int i=l, j=mid+1;
vector<int> temp; //记录当前归并时候最终有序的数组
//归并过程
while(i<=mid && j<=r)
{
if(nums[i] <= nums[j]) temp.push_back(nums[i ++]);
else{
//逆序对
temp.push_back(nums[j ++]);
(res += mid -i +1) %= 1000000007;
}
}
//存在某个区间没有比较完毕,直接push
while(i <= mid) temp.push_back(nums[i ++]);
while(j <= r) temp.push_back(nums[j ++]);
i=l;
for(auto x : temp) nums[i ++] = x;
return res;
}
int InversePairs(vector<int> data) {
return merge(data, 0, data.size()-1);
}
};
第八题:数值在升序数组中出现的次数
class Solution {
public:
int GetNumberOfK(vector<int> data ,int k) {
if(!data.size()) return NULL;
int time=0;
int i=0;
//找出从哪开始出现相同数字
while(i<data.size())
{
if(data[i]==k)
{
break;
}
else
i++;
}
//统计出现几次
while(i<data.size())
{
if(data[i]!=k)
{
break;
}
i++;
time++;
}
return time;
}
};
//因为data中都是整数,所以可以稍微变一下,不是搜索k的两个位置,而是搜索k-0.5和k+0.5
//这两个数应该插入的位置,然后相减即可。
class Solution {
public:
int GetNumberOfK(vector<int> data ,int k) {
return biSearch(data,k+0.5) - biSearch(data,k-0.5);
}
int biSearch(const vector<int>& data,double num)
{
int s=0, e=data.size()-1;
while(s <= e)
{
int mid=(e-s)/2 +s;
if(data[mid] < num)
s=mid+1;
else if(data[mid]>num)
e=mid-1;
}
return s;
}
};
第九题:数组中只出现一次的两个数字
题解地址:https://www.acwing.com/video/196/
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param array int整型vector
* @return int整型vector
*/
vector<int> FindNumsAppearOnce(vector<int>& array) {
// write code here
int sum=0; //sum为所有数字的异或和,因为只有两个数字只出现一次,所以sum = x ^ y;
for(auto x:array) sum ^= x;
int k=0; //k记录sum异或中的某一位为1的位置
while(!(sum >> k & 1)) k++;
int num1=0,num2=0;
//对所有第k位为1的进行异或,得到出现一次的数字
for(auto x:array)
if(x>>k & 1)
num1 ^= x;
//num2 = sum ^ num1;
num2 = sum ^ num1;
if(num1<num2)
return vector<int>{num1,num2};
else
return vector<int>{num2,num1};
}
};
第十题:数组中重复的数字
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param numbers int整型vector
* @return int整型
*/
int duplicate(vector<int>& numbers) {
// write code here
if(numbers.size()<=1) return -1;
unordered_map<int, int>map;
for(int i=0;i<numbers.size();i++)
{
map[numbers[i]]++;
if(map[numbers[i]]>1) return numbers[i];
}
return -1;
}
};
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param numbers int整型vector
* @return int整型
*/
int duplicate(vector<int>& numbers) {
// write code here
int n=numbers.size();
for(int i=0; i<n; i++)
{
if(numbers[i]<0 || numbers[i] >= n) return -1;
while(i != numbers[i] && numbers[numbers[i]] != numbers[i]) swap(numbers[i], numbers[numbers[i]]);
if(numbers[i] != i && numbers[numbers[i]] == numbers[i]) return numbers[i];
}
return -1;
}
};