主要目录
1991. 找到数组的中间位置、724. 寻找数组的中心下标
零、写在前面
这是打卡的第十八天,今天题目比较简单,就是题量巨大,补充一个知识点,主要知识点在
一、主要知识点
1.十进制的数位数是否为偶数
主要利用到的思想就是先确定位数,然后看是否为偶数。
bool weishu(int n){
int count = 0; //初始化个数
while(n){
count ++;
n /= 10; //数数
}
return !(count & 1); //判断是否为偶数
}
2.前缀和
有个东西我们可以求一个数组的前缀和,很多题都需要用到。
int pivotIndex(int* nums, int numsSize){
int total = 0, sum = 0;
for(int i = 0; i < numsSize;i++)
total += nums[i]; //统计全和
for(int i = 0; i < numsSize;sum += nums[i],i++)
if(sum * 2 == total - nums[i]) return i; //sum统计前缀和进行判断
return -1;
}
二、课后习题
1295. 统计位数为偶数的数字
1295. 统计位数为偶数的数字https://leetcode-cn.com/problems/find-numbers-with-even-number-of-digits/
主要思想
从前到后扫描,用变量计数,更新结果就好了。。看代码
bool weishu(int n){ //判断是否为偶数,看知识点
int count = 0;
while(n){
count ++;
n /= 10;
}
return !(count&1);
}
int findNumbers(int* nums, int numsSize){
int count = 0;
for(int i = 0;i < numsSize;i++)
if(weishu(nums[i])) count++;//满足条件的计数
return count;
}
结果分析
总觉得,力扣的4ms和0ms差距不大 233
540. 有序数组中的单一元素
540. 有序数组中的单一元素https://leetcode-cn.com/problems/single-element-in-a-sorted-array/
主要思想
利用二分的思想,判断中间的值是否和后面的值相等。其中含有只有一个元素的串的长度一定为奇数。
int singleNonDuplicate(int* nums, int numsSize){
int low = 0,high = numsSize - 1;//二分初始值
while(low < high){ //二分跳出条件
int mid = (low + high) /2; //二分中间位置
if(mid % 2 == 1) mid--; //只判断偶数位
if(nums[mid] == nums[mid + 1]) low = mid +2;//中间两个相同,所以直接返回高位
else high = mid; //无法判断中间位置,但是后面个数为偶数 所以返回前面
}
return nums[low];
}
结果分析
凑合,还行。
剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
主要思想
两个指针,一个在前,一个在后,一共往后扫找偶数,一个往前扫找奇数,找到后交换就行了呗。
int* exchange(int* nums, int numsSize, int* returnSize){
int i = 0 , j = numsSize - 1;
*returnSize = numsSize;
while(i < j){
while((nums[i]&1)&&i < j) //找到第一个偶数
i++;
while((!(nums[j]&1))&& i < j) //找到第一个奇数
j--;
if(i < j){
nums[i] = nums[i] ^ nums[j];//交换i j对应元素
nums[j] = nums[i] ^ nums[j];
nums[i] = nums[i] ^ nums[j];
}
else break;
}
return nums;
}
结果分析
还行吧。
1991. 找到数组的中间位置、724. 寻找数组的中心下标
724. 寻找数组的中心下标https://leetcode-cn.com/problems/find-pivot-index/
1991. 找到数组的中间位置https://leetcode-cn.com/problems/find-the-middle-index-in-array/
主要思想
还记得我知识点说到的前缀和么,就是这道题。。按照说的来就好了。这两道题是一样的一起来吧。
int findMiddleIndex(int* nums, int numsSize){
int total = 0, sum = 0;
for(int i = 0; i < numsSize;i++)
total += nums[i]; //全部和
for(int i = 0; i < numsSize;sum += nums[i],i++)
if(sum * 2 == total - nums[i]) return i;//满足条件返回
return -1;
}
结果分析
可以了
26. 删除有序数组中的重复项
26. 删除有序数组中的重复项https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/
主要思想
统计重复元素,把非重复元素前移就好了。
int removeDuplicates(int* nums, int numsSize){
int count = 0;
for(int i = 1;i < numsSize; ++i){
if(nums[i] == nums[i - count - 1]) //重复元素 统计
count ++;
else nums[i - count] = nums[i]; //非重复元素前移
}
return numsSize - count; //返回值
}
结果分析
简洁,完美
1018. 可被 5 整除的二进制前缀
1018. 可被 5 整除的二进制前缀https://leetcode-cn.com/problems/binary-prefix-divisible-by-5/
主要思想
这道题就是按照要求算就好了,但是要注意会超出范围,及时取余。
返回数组需要malloc,之前之一注意堆栈的我竟然忘了。。。
bool* prefixesDivBy5(int* nums, int numsSize, int* returnSize){
bool * ans = malloc(sizeof(bool) * numsSize);//申请堆空间
int temp; //记录当前值
*returnSize = numsSize;
for(int i = 0; i < numsSize; i++){
temp <<= 1; //移位2进制
temp += nums[i]; //将个位插入
temp %= 5;
if(temp % 5) ans[i] = false;
else ans[i] = true;
}
return ans;
}
结果分析
凑合
1015. 可被 K 整除的最小整数
1015. 可被 K 整除的最小整数https://leetcode-cn.com/problems/smallest-integer-divisible-by-k/
主要思想
这个要注意死循环,因为1111生成过程中为*10,所以必然不包含2和5的因子,所以要排除。
int smallestRepunitDivByK(int k){
if(k % 2 == 0 || k % 5 == 0) return -1;//排除情况
int temp = 0,i = 0;
while(++i){
temp *= 10;
temp++;
temp %= k;//及时取余计算防止溢出
if(temp % k == 0) return i;
}
return 0;
}
结果分析
还行
1869. 哪种连续子字符串更长
1869. 哪种连续子字符串更长https://leetcode-cn.com/problems/longer-contiguous-segments-of-ones-than-zeros/
主要思想
直接统计最大1和最小0的字串比较就好了
bool checkZeroOnes(char * s){
int max1 = 0,max0 = 0;
for(int i = 0;s[i] != 0;){ //内部有i++这里不能加i++ 否则结果不对
int count0 = 0,count1 = 0;
while(s[i] == '0'){//统计1的数字
count0 ++;
i++;
}
while(s[i] == '1'){//统计0的数字
count1++;
i++;
}
max1 = count1 > max1 ? count1 : max1;
max0 = count0 > max0 ? count0 : max0;
}
return max1 > max0;
}
结果分析
还行
三、今日总结
今天的难度不高,就是题量大,写论文去咯-.-。。。。