还是继续向后学习两道题,希望慢慢让自己习惯用于编程的思维方式。今天的两道题还是有关数组的题目。
加一
第一道题是第66题,给定一个数组,数组中的每个元素代表一个整数中的每一位,最高位位于数组的头部,随后将这个数字进行加一,最后返回数组长度以及加一后的数组。其实就是整数加一,利用数组模拟了这个加一的过程,需要思考的地方就是如何模拟出逢十进位的过程。
为了解决这个问题,首先想到的是倒序遍历数组,只要检测到9就将这一位赋零,使其前一位进行加一操作,如果前一位还是9就继续让前一位加1,但是最后都会遇到一个问题是如果全部是9,不如999,加一后得到1000,原先的数组就没有办法存储。为了解决这个问题就用malloc定义了一个新的数组用来存储答案,这个数组比原数组多一位,为了防止出现多一位数不够空间存储的情况。那么对于两个数组的操作,需要用到两个数来指示在每个数组中的位置。而用来标志是否有进位情况,则是题解中给我的思路,用一个整数是否为1标志是否存在进位情况,如果倒序遍历到9,就将0赋给答案数组中的相应位置,最后答案数组中留下的第一位是预留给增大一位数后的1,如果进位标志一直存在,那么就将答案数组的第一位赋1,即可解决之前的情况。如果进位标志不为1,那么就将答案数组中的数整体向前挪一位,得到最终的答案。
int* plusOne(int* digits, int digitsSize, int* returnSize) {
int* ans = (int*)malloc(sizeof(int) * (digitsSize + 1));
int carry = 1;
int cur1 = digitsSize - 1;
int cur2 = digitsSize;
while (cur1 >= 0)
{
ans[cur2] = (digits[cur1] + carry) % 10;
carry = (carry + digits[cur1]) / 10;
cur1--;
cur2--;
}
if (carry == 0)
{
for (int i = 0; i < digitsSize; i++)
{
ans[i] = ans[i + 1];
}
(*returnSize) = digitsSize;
}
else
{
ans[0] = 1;
(*returnSize) = digitsSize + 1;
}
return ans;
}
移动零
移动零是第283题,就是将数组中的0全部移动到数组的末尾,而将其余不为零的元素按照原顺序紧凑排列在原数组中。一开始想的是直接检测零,如果有零就将后面的数向前移,再将最后一个元素赋为零,但是这里出现的问题是将后面的数向前移动了之后,用于指示遍历进程的整数应该减1,检验原先为0位置的新元素是否为0,但是编写过程中一直没有想到方法通过。后来就将思路反过来,将不为零的数按顺序紧凑存储在数组中,最后将后面剩的位置补零。
void moveZeroes(int* nums, int numsSize) {
int i = 0, j = 0;
for (i = 0; i < numsSize; i++) {
if (nums[i] != 0) {
nums[j] = nums[i];
j++;
}
}
for (i = j; i < numsSize; i++) {
nums[i] = 0;
}
}
今天看完感觉自己的思路还是不够灵活,以及对一些基本操作的理解不够深入,这些都还需要花些时间自己再仔细思考一番。