67. 二进制求和
题目描述
67. 二进制求和
给你两个二进制字符串 a
和 b
,以二进制字符串的形式返回它们的和。
运行代码(java+C++)
class Solution {
public String addBinary(String a, String b) {
StringBuilder ans=new StringBuilder();
int ca=0;
for(int i=a.length()-1,j=b.length()-1;i>=0||j>=0;i--,j--){
int sum=ca;
sum+=i>=0?a.charAt(i)-'0':0;
sum+=j>=0?b.charAt(j)-'0':0;
ans.append(sum%2);
ca=sum/2;
}
ans.append(ca==1?ca:"");
return ans.reverse().toString();
}
}
class Solution {
public:
string addBinary(string a, string b) {
string ans;
int ca = 0;
int i = a.length() - 1;
int j = b.length() - 1;
while (i >= 0 || j >= 0) {
int sum = ca;
sum += (i >= 0)? a[i] - '0' : 0;
sum += (j >= 0)? b[j] - '0' : 0;
ans += to_string(sum % 2);
ca = sum / 2;
i--;
j--;
}
if (ca == 1) ans += to_string(ca);
reverse(ans.begin(), ans.end());
return ans;
}
};
代码思路
-
初始化:定义一个字符串
ans
用于存储最终的二进制和结果。定义变量ca
作为进位标志,初始值为 0。定义两个指针i
和j
,分别指向输入字符串a
和b
的最后一个字符,即从最低位开始进行加法运算。 -
逐位相加:
- 进入循环,条件是
i >= 0
或者j >= 0
,即只要两个字符串中还有未处理的位就继续循环。 - 计算当前位的和
sum
,首先将进位标志ca
加入,然后如果i
指针指向的位置有效(即i >= 0
),将字符串a
中当前位的值(转换为数字)加入sum
;如果j
指针指向的位置有效(即j >= 0
),将字符串b
中当前位的值(转换为数字)加入sum
。 - 将
sum
对 2 取余的结果转换为字符串并添加到ans
中,这就是当前位的结果(0 或 1)。 - 更新进位标志
ca
为sum
除以 2 的结果。移动指针i
和j
分别向左一位。
- 进入循环,条件是
-
处理进位:循环结束后,如果进位标志
ca
为 1,说明还有一个进位需要添加到结果中,将ca
转换为字符串并添加到ans
。 -
反转结果:由于是从低位向高位计算,所以最后需要将结果字符串
ans
反转,得到正确的二进制和。 -
返回结果:返回最终的二进制和字符串
ans
。
27. 移除元素
题目描述
27. 移除元素
给你一个数组 nums
和一个值 val
,你需要 原地 移除所有数值等于 val
的元素。元素的顺序可能发生改变。然后返回 nums
中与 val
不同的元素的数量。
假设 nums
中不等于 val
的元素数量为 k
,要通过此题,您需要执行以下操作:
- 更改
nums
数组,使nums
的前k
个元素包含不等于val
的元素。nums
的其余元素和nums
的大小并不重要。 - 返回
k
。
用户评测:
评测机将使用以下代码测试您的解决方案:
int[] nums = [...]; // 输入数组 int val = ...; // 要移除的值 int[] expectedNums = [...]; // 长度正确的预期答案。 // 它以不等于 val 的值排序。 int k = removeElement(nums, val); // 调用你的实现 assert k == expectedNums.length; sort(nums, 0, k); // 排序 nums 的前 k 个元素 for (int i = 0; i < actualLength; i++) { assert nums[i] == expectedNums[i]; }
如果所有的断言都通过,你的解决方案将会 通过
运行代码
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
for(auto iter = nums.begin(); iter != nums.end();)
{
if(*iter == val)
{
iter = nums.erase(iter);
}
else
{
++iter;
}
}
return nums.size();
}
};
代码思路
-
遍历数组:
- 使用迭代器
iter
遍历输入的整数向量nums
。从nums.begin()
开始,一直到nums.end()
。 - 在每次循环中,检查当前迭代器指向的元素是否等于给定的值
val
。
- 使用迭代器
-
删除等于给定值的元素:
- 如果当前元素等于
val
,则调用nums.erase(iter)
来删除该元素。erase
函数会返回一个指向下一个有效元素的迭代器,将其赋值给iter
,以便继续遍历。 - 如果当前元素不等于
val
,则递增迭代器iter
,指向下一个元素。
- 如果当前元素等于
-
返回结果:最后,返回
nums
的大小,即经过删除操作后剩余元素的数量。
26. 删除有序数组中的重复项
题目描述
26. 删除有序数组中的重复项
给你一个 非严格递增排列 的数组 nums
,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums
中唯一元素的个数。
考虑 nums
的唯一元素的数量为 k
,你需要做以下事情确保你的题解可以被通过:
- 更改数组
nums
,使nums
的前k
个元素包含唯一元素,并按照它们最初在nums
中出现的顺序排列。nums
的其余元素与nums
的大小不重要。 - 返回
k
。
判题标准:
系统会用下面的代码来测试你的题解:
int[] nums = [...]; // 输入数组 int[] expectedNums = [...]; // 长度正确的期望答案 int k = removeDuplicates(nums); // 调用 assert k == expectedNums.length; for (int i = 0; i < k; i++) { assert nums[i] == expectedNums[i]; }
如果所有断言都通过,那么您的题解将被 通过。
运行代码
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int n=nums.size();
if(n==0){
return 0;
}
int fast=1,slow=1;
while(fast<n){
if(nums[fast]!=nums[fast-1]){
nums[slow]=nums[fast];
++slow;
}
++fast;
}return slow;
}
};
代码思路
-
边界情况处理:首先检查输入向量
nums
的大小是否为 0。如果是,则直接返回 0,表示没有任何元素,也没有不重复的元素。 -
初始化指针:定义两个指针
fast
和slow
,分别用于快速遍历整个数组和标记不重复元素的位置。初始时,将fast
和slow
都设置为 1,表示从第二个元素开始检查重复情况。 -
遍历数组:
- 进入
while
循环,条件是fast
小于数组的大小n
。这个循环的目的是通过fast
指针快速遍历整个数组,找到不重复的元素。 - 在每次循环中,检查当前
fast
指针指向的元素是否与前一个元素(nums[fast - 1]
)不同。 - 如果不同,说明找到了一个不重复的元素,将其赋值给
slow
指针指向的位置(nums[slow] = nums[fast]
),然后将slow
指针向后移动一位(++slow
)。
- 进入
-
移动指针:无论当前元素是否重复,都将
fast
指针向后移动一位(++fast
),继续检查下一个元素。 -
返回结果:循环结束后,
slow
指针的值表示不重复元素的数量。返回slow
作为结果,它代表了删除重复元素后数组的新长度。