66. 加一
给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
示例 1:
输入:digits = [1,2,3] 输出:[1,2,4] 解释:输入数组表示数字 123。
示例 2:
输入:digits = [4,3,2,1] 输出:[4,3,2,2] 解释:输入数组表示数字 4321。
示例 3:
输入:digits = [0] 输出:[1]
提示:
-
1 <= digits.length <= 100
-
0 <= digits[i] <= 9
题解:
class Solution {
public:
vector<int> plusOne(vector<int>& digits) {
//后缀法,矛盾在于是否+1后会发生多少次进位
//1.不进位则+1
//2.只是部分进位
//3.全进位
int n = digits.size();
for(int i = n - 1; i >= 0; --i) {
if(digits[i] != 9) {
++digits[i];
int j = i + 1;
while(j < n) {
digits[j++] = 0;
}
return digits;
}
}
vector<int> ans(n + 1, 0);
ans[0] = 1;
return ans;
}
};
1822. 数组元素积的符号
已知函数 signFunc(x)
将会根据 x
的正负返回特定值:
-
如果
x
是正数,返回1
。 -
如果
x
是负数,返回-1
。 -
如果
x
是等于0
,返回0
。
给你一个整数数组 nums
。令 product
为数组 nums
中所有元素值的乘积。
返回 signFunc(product)
。
示例 1:
输入:nums = [-1,-2,-3,-4,3,2,1] 输出:1 解释:数组中所有值的乘积是 144 ,且 signFunc(144) = 1
示例 2:
输入:nums = [1,5,0,2,-3] 输出:0 解释:数组中所有值的乘积是 0 ,且 signFunc(0) = 0
示例 3:
输入:nums = [-1,1,-1,1,-1] 输出:-1 解释:数组中所有值的乘积是 -1 ,且 signFunc(-1) = -1
提示:
-
1 <= nums.length <= 1000
-
-100 <= nums[i] <= 100
题解
class Solution {
public:
int arraySign(vector<int>& nums) {
//判断是否有0,有0则输出0结束
//判断负数的个数,如果为偶数则为1,奇数则为0
//基本思想:遍历数组,对值进行条件判断
short int isOddNumber = 1;
for (const auto& i : nums)
{
if (i == 0)return 0;
else
{
isOddNumber = i > 0 ?isOddNumber:-isOddNumber;
}
}
return isOddNumber;
}
};
1502. 判断能否形成等差数列
给你一个数字数组 arr
。
如果一个数列中,任意相邻两项的差总等于同一个常数,那么这个数列就称为 等差数列 。
如果可以重新排列数组形成等差数列,请返回 true
;否则,返回 false
。
示例 1:
输入:arr = [3,5,1] 输出:true 解释:对数组重新排序得到 [1,3,5] 或者 [5,3,1] ,任意相邻两项的差分别为 2 或 -2 ,可以形成等差数列。
示例 2:
输入:arr = [1,2,4] 输出:false 解释:无法通过重新排序得到等差数列。
提示:
-
2 <= arr.length <= 1000
-
-10^6 <= arr[i] <= 10^6
题解1:从小到大排序,用通项公式判断,时间复杂度O(n*logn)
class Solution {
public:
//从小到大排序,用通项公式判断
bool canMakeArithmeticProgression(vector<int>& arr) {
unsigned int len = arr.size();
if(len == 2) return true;
sort(arr.begin(), arr.end());
//An = a1 + d*n;
unsigned short int d = arr[1] - arr[0];
for(int i = 2; i < len; ++i)
{
if(arr[i] != arr[i-1] + d)
return false;
}
return true;
}
};
题解2:时间复杂度O(n)
class Solution {
public:
bool canMakeArithmeticProgression(vector<int>& arr) {
int minNum = INT_MAX, maxNum = INT_MIN;
unordered_map<int, int> map;
int diff;
for(int num : arr){
map[num]++; // 统计每个数字出现的次数
minNum = min(minNum, num); // 找到最小值
maxNum = max(maxNum, num); // 找到最大值
}
if(maxNum == minNum)
return true; // 如果最大值等于最小值,说明所有元素都相同,可以构成等差数列
if((maxNum - minNum) % (arr.size() - 1))
return false; // 如果最大值和最小值之间的差不能被数组长度减一整除,说明无法构成等差数列
else
diff = (maxNum - minNum) / (arr.size() - 1); // 计算公差
for(int i = minNum; i <= maxNum; i+=diff){
if(map.find(i) == map.end())
return false; // 如果某个数字在数组中不存在,说明无法构成等差数列
}
return true; // 如果所有数字都存在且满足等差数列的条件,则返回true
}
};
首先初始化了两个变量minNum
和maxNum
,分别用于存储数组中的最小值和最大值。然后,使用一个无序映射map
来统计每个数字出现的次数。接下来,通过遍历数组,更新最小值和最大值,并将每个数字的出现次数记录到映射中。
接着,函数检查最大值是否等于最小值。如果是,说明所有元素都相同,可以构成等差数列,直接返回true
。否则,函数计算最大值和最小值之间的差,并检查该差是否能被数组长度减一整除。如果不能整除,说明无法构成等差数列,返回false
。如果可以整除,则计算公差diff
。
最后,函数再次遍历从最小值到最大值的范围,检查每个数字是否存在于映射中。如果有任何一个数字不存在,说明无法构成等差数列,返回false
。如果所有数字都存在且满足等差数列的条件,则返回true
。