如果整个数组非递减,返回true,如果只有两个子数列非递减,并且两个子序列之间是有序的,返回true。
先找到第一个不满足非递减的位置i,如果i==numsize,说明整个数组非递减。否则,就判断另一个子数组是否是非递减的,若不是,返回false,若是,则判断两个子数组之间是否有序,只需要判断nums[0]与nums[numsize-1]的大小。nums[0]是第一个子数组的最小值,nums[numsize-1]是第二个子数组的最大值。
bool check(int* nums, int numsSize) {
//需要满足数组是非递减的,或者有两个子序列非递减,且两个子序列是有序的
int i,j;
for(i=1;inums[i]){
break;
}
}
if(i==numsSize){//数组非递减
return true;
}
for(int j=i+1;jnums[j]){
return false;
}
}
if(nums[0]>=nums[numsSize-1]){//判断两个子数组是否有序,
return true;
}
return false;
}
模拟,一次遍历。用cur记录当前最大子数组和,升序cur就加nums[i],破坏了升序就让cur=nums[i]
int maxAscendingSum(int* nums, int numsSize) {
//模拟
int ans=0,cur=0;
for(int i=0;ians) ans=cur;
}else{
cur=nums[i];
}
}
return ans;
}
一次遍历,如果nums[i-1]>=nums[i],就更新nums[i]。采用贪心的思想,遍历数组进行判断当前局部是否满足递增,不满足就进行操作使其递增。
int minOperations(int* nums, int numsSize){
int ans=0;
for(int i=1;i=nums[i]){
ans+=nums[i-1]+1-nums[i];
nums[i]=nums[i-1]+1;
}
}
return ans;
}
该题可以住转化为找数组中是否有且仅有一个驼峰或者低谷元素,这里需要注意是三个元素都有严格的大小,只要有一个不满足就不行。
bool canBeIncreasing(int* nums, int numsSize) {
if(numsSize<=2) return true;
bool flag=true;//判断是否找到一个驼峰或者低谷
for(int i=0;i=nums[i+1]){
if(flag){
if(i-1<0||nums[i+1]>nums[i-1]) flag=false;//遇到的是驼峰
else if(i+2>=numsSize||nums[i+2]>nums[i]) flag=false;//遇到的是低谷
else return false;
}else{
//第二次遇到
return false;
}
}
}
return true;
}
排序+辗转相除法
int gcd(int x,int y){
//辗转相除法
if(y==0){
return x;
}
return gcd(y,x%y);
}
int cmp(void* a,void *b){
return *(int*)a-*(int*)b;
}
int findGCD(int* nums, int numsSize) {
qsort(nums,numsSize,sizeof(int),cmp);//排序
return gcd(nums[0],nums[numsSize-1]);
}
关键是左右侧元素相等即为 sum=total−nums[i]−sum
int findMiddleIndex(int* nums, int numsSize) {
//左右侧元素相等即为 sum=total−nums[i]−sum
int total=0;
for(int i=0;i
要点:3位数,偶数,且三个数字要不同,第一个数字不能是0,且不能有重复的答案,最后输出必须按升序排序
class Solution {
public:
vector findEvenNumbers(vector& digits) {
unordered_set s;//用于去重
int n=digits.size();
for(int i=0;i res;
for(int num:s){
res.push_back(num);
}
sort(res.begin(),res.end());
return res;
}
};
int cmp(void* a,void*b){
return *(int*)a-*(int*)b;
}
int findClosestNumber(int* nums, int numsSize) {
qsort(nums,numsSize,sizeof(int),cmp);
int index=0;//第一个为正的数字
while(indexabs(nums[index-1])){
return nums[index-1];
}
return nums[index];
}
int findClosestNumber(int* nums, int numsSize) {
int res=nums[0];
int dis=abs(nums[0]);
for(int i=1;ires){
res=nums[i];
}
}
}
return res;
}
int fun(int *nums,int numsSize){
//找出最小正数
int mm=INT_MAX;
for(int i=0;i0&&nums[i]
由于每次减去一个数组中的最小的正数,只有当正数不相同时,需要操作的次数才会增加,因此问题转化为了找数组中有几个不同的正数。
class Solution {
public:
int minimumOperations(vector& nums) {
unordered_set s;//set天然去重
for(int num:nums){
if(num>0){
s.emplace(num);
}
}
return s.size();
}
};
bool findSubarrays(int* nums, int numsSize) {
for(int i=0;i
class Solution {
public:
bool findSubarrays(vector& nums) {
unordered_set s;
for(int i=0;i
class Solution {
public:
vector answerQueries(vector& nums, vector& queries) {
vector res;
sort(nums.begin(),nums.end());
for(int target:queries){
int ans=0;
int sum=0;
for(int i=0;itarget){
ans--;
break;
}
}
res.push_back(ans);
}
return res;
}
};
class Solution {
public:
vector answerQueries(vector& nums, vector& queries) {
vector res;
sort(nums.begin(),nums.end());
for(int i=1;i
用数组做哈希表,数字很大,占用空间不小。
int mostFrequentEven(int* nums, int numsSize) {
int flag[100002]={0};
int res=-1;
int mmax=0;
for(int i=0;immax||flag[nums[i]]==mmax&&nums[i]
判断回文字符串,然后遍历判断。
class Solution {
public:
bool fun(string str){
int n=str.size();
for(int i=0;i& words) {
for(string str:words){
if(fun(str)){
return str;
}
}
return "";
}
};
给你一个整数数组
nums
,另给你一个整数original
,这是需要在nums
中搜索的第一个数字。接下来,你需要按下述步骤操作:
- 如果在
nums
中找到original
,将original
乘以 2 ,得到新original
(即,令original = 2 * original
)。- 否则,停止这一过程。
- 只要能在数组中找到新
original
,就对新original
继续 重复 这一过程。
此题用递归的思想。代码简洁,但开销较大。
int findFinalValue(int* nums, int numsSize, int original) {
for(int i=0;i
模拟,用两个数组分别记录奇偶下标的元素,分别进行排序之后,在写回nums数组中。
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int cmp1(int *e1,int *e2) {
//降序
return *e2 - *e1;
}
int cmp2(int *e1,int *e2) {
//升序
return *e1 - *e2;
}
int* sortEvenOdd(int* nums, int numsSize, int* returnSize){
*returnSize = numsSize;
int n=(numsSize+1)/2;
int odd[n],even[n],len1 = 0,len2 = 0,i;
// 取出奇数和偶数
for (i = 0; i < numsSize; i++) {
if (i%2==1) {
odd[len1++] = nums[i];
} else {
even[len2++] = nums[i];
}
}
qsort(odd,len1,sizeof(int),cmp1);
qsort(even,len2,sizeof(int),cmp2);
for (i = len1 = len2 = 0; i < numsSize; i++) {
if (i%2==1) nums[i] = odd[len1++];
else nums[i] = even[len2++];
}
return nums;
}
对字符串进行操作,复习strncmp()函数:
int strncmp(const char *str1, const char *str2, size_t n)
把str1
和str2
进行比较,最多比较前n
个字节。返回值为:
- 按照
ASCII
值进行比较,str1-str2
的数值就是返回值。- 如果返回值
<
0,则表示str1
小于str2
。- 如果返回值
>
0,则表示str2
小于str1
。- 如果返回值
=
0,则表示str1
等于str2
。
int prefixCount(char** words, int wordsSize, char* pref) {
int res=0;
int len=strlen(pref);
for(int i=0;i
此题的难点的是需要跨越多个值进行判断峰和谷,相等的数字应该跳过,需要比较的是不同的值。
int countHillValley(int* nums, int numsSize) {
//从三个数中去找小于或大于两边的数组的个数,若数对中有两个数相等,就跳过相等的数去寻找下一个不相等的数由此构成新的数对,再判断是否符合条件
int ans=0;
int temp=nums[0];
for(int i=1;inums[i+1]&&nums[i]>temp){//遇到峰,ans加1
ans++;
}else if(nums[i]
题目:给你一个下标从 0 开始的整数数组
nums
,该数组的大小为n
,请你计算nums[j] - nums[i]
能求得的 最大差值 ,其中0 <= i < j < n
且nums[i] < nums[j]
。返回 最大差值 。如果不存在满足要求的
i
和j
,返回-1
。
int maximumDifference(int* nums, int numsSize) {
int ans=-1;
for(int i=0;i0&&cur>ans){
ans=cur;
}
}
}
return ans;
}
int maximumDifference(int* nums, int numsSize) {
int ans=-1;
int premin=nums[0];
for(int i=1;ipremin){
if(nums[i]-premin>ans){
ans=nums[i]-premin;//ans=max(ans,nums[i]-premin)
}
}else{
premin=nums[i];
}
}
return ans;
}