66.加一
题目描述[简单]:
给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
翻译一下:
数组每位都是single digit,所以只能是0-9的个位数,整个数没有leading zero,意思就是数组第一个数必非0,再就是要注意,像[9,9]输出就是[1,0,0]。
示例1:
输入:digits = [1,9,9,]
输出:[2,0,0]
解释:输入数组表示数字 199。
思路[暴力]:
从后往前遍历digits数组,如果遇到9就变成0,如果遇到不是9就+1。如果全部都是进位,则构造一个新的数组,在经过for之后,全为0了,此时让第一位即digit[0]=1。
C++代码:
class Solution {
public:
vector<int> plusOne(vector<int>& digits) {
for(int i = digits.size() - 1 ; i >= 0 ; i--){
if(digits[i] == 9){
digits[i] = 0 ;
}
else {
digits[i] += 1;
return digits ;
}
}
//如果所有位都是进位,则长度+1
vector<int> digit(digits.size() + 1);//构造一个新的数组
digit[0] = 1;//在第一个for的基础上全是0,现在让他的最高位即digit[0]=1即可。
return digit;
}
};
执行结果:
67.二进制求和
题目描述[简单]:
给你两个二进制字符串,返回它们的和(用二进制表示)。
输入为 非空 字符串且只包含数字 1 和 0。
示例1:
输入: a = “11”, b = “1”
输出: “100”
思路:
二进制进位核心就是满二进一。
1.让两个字符串等长,若不等长,在短的字符串前补零。
2.从后到前遍历所有位数,同位相加。(字符相加,可以利用 ASCII 码。字符在内部用数字表示,我们不需要知道具体数值,但我们可知 0 - 0 = 0, 0 +1 = 1)字符加减,实际上都是内部数字的加减。
3.判断相加后的字符,若大于等于2,下一位需要进1。
第 0位数的相加在这里是单独处理的,因为它可能涉及到字符的插入(即是否需要在最前面加一位数1)
C++代码:
class Solution {
public:
string addBinary(string a, string b) {
int al = a.size();
int bl = b.size();
while(al < bl) //让两个字符串等长,若不等长,在短的字符串前补零
{
a = '0' + a;
++ al;
}
while(al > bl)
{
b = '0' + b;
++ bl;
}
for(int j = a.size() - 1; j > 0; -- j) //从后到前遍历所有的位数,同位相加
{
a[j] = a[j] - '0' + b[j];
if(a[j] >= '2') //若大于等于字符‘2’,需要进1
{
a[j] = (a[j] - '0') % 2 + '0';
a[j-1] = a[j-1] + 1;
}
}
a[0] = a[0] - '0' + b[0]; //将a、b的第0位相加
if(a[0] >= '2') //若大于等于2,需要进1
{
a[0] = (a[0] - '0') % 2 + '0';
a = '1' + a;
}
return a;
}
};
这一题算法其实算不上什么好,但是是我最容易懂的,因为那个通过翻转的办法我不是很好理解。所以写了一种我好理解的代码。
69.x的平方根
题目描述[简单]:
给你一个非负整数 x ,计算并返回 x 的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
示例 1:
输入:x = 8
输出:2
解释:8 的算术平方根是 2.82842…, 由于返回类型是整数,小数部分将被舍去。
思路[二分查找]:
由于 x 平方根的整数部分 res是满足 k^2 ≤ x 的最大 k 值,因此我们可以对 k 进行二分查找,从而得到答案。
二分查找的下界为 0,上界可以粗略地设定为x。在二分查找的每一步中,我们只需要比较中间元素mid 的平方与 x 的大小关系,并通过比较的结果调整上下界的范围。
C++代码
class Solution {
public:
int mySqrt(int x) {
int left = 0, right = x, res = -1;
while (left <= right) {
int mid = left + (right - left) / 2;
if ((long long)mid * mid <= x) {
res = mid;
left = mid + 1;
} else {
right = mid - 1;
}
}
return res;
}
};
结果分析:
时间复杂度:O(\log x)O(logx),即为二分查找需要的次数。