分治法
顾名思义,分治问题由“分”(divide)和“治”(conquer)两部分组成,通过把原问题分为子问题,再将子问题进行处理合并,从而实现对原问题的求解。我们在排序章节展示的归并排序就是典型的分治问题,其中“分”即为把大数组平均分成两个小数组,通过递归实现,最终我们会得到多个长度为 1 的子数组;“治”即为把已经排好序的两个小数组合成为一个排好序的大数组,从长度为 1 的子数组开始,最终合成一个大数组。
(1)241. Different Ways to Add Parentheses (Medium)
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
题目描述
给定一个只包含加、减和乘法的数学表达式,求通过加括号可以得到多少种不同的结果。
个人思路
利用分治思想,我们可以把加括号转化为,对于每个运算符号,先执行处理两侧的数学表达式,再处理此运算符号。注意边界情况,即字符串内无运算符号,只有数字。
代码展示
vector<int> diffWaysToCompute(string expression) {
vector<int> ans;
vector<int> left;
vector<int> right;
for(int i=0;i<expression.length();i++){
char c=expression[i];
if(c=='+'||c=='-'||c=='*'){
left=diffWaysToCompute(expression.substr(0,i));
right=diffWaysToCompute(expression.substr(i+1));
for(const int& l:left){
for(const int& r:right){
int result;
switch(c){
case '+': result = l + r; break;
case '-': result = l - r; break;
case '*': result = l * r; break;
}
ans.push_back(result);
}
}
}
}
if(ans.empty()){ // 处理表达式是纯数字的情况
ans.push_back(stoi(expression));
}
return ans;
}
位运算
位运算是算法题里比较特殊的一种类型,它们利用二进制位运算的特性进行一些奇妙的优化和计算。常用的位运算符号包括:“∧”按位异或、“&”按位与、“|”按位或、“∼”取反、“<<”算术左移和“>>”算术右移。
(1)461. Hamming Distance (Easy)
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
题目描述
给定两个十进制数字,求它们二进制表示的汉明距离(Hamming distance,即不同位的个数)。
个人思路
没啥好说的,对两个数进行按位异或操作,统计有多少个 1 即可。
代码展示
int hammingDistance(int x, int y) {
int diff = x ^ y, ans = 0;
while (diff) {
ans += diff & 1;
diff >>= 1;
}
return ans;
}
(2)190. Reverse Bits (Easy)
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
题目描述
给定一个32位十进制整数,输出它在二进制下的翻转结果。
个人思路
这个和第一题的思路是一样的,都比较简单,唯一需要注意的一点就是必须要把32位遍历完(0也得补上),不然会error。
代码展示
uint32_t reverseBits(uint32_t n) {
uint32_t ans=0;
int k=32;
while(k>0){
ans<<=1;
ans+=n&1;
n>>=1;
k--;
}
return ans;
}
(3)136.Single Number (Easy)
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
题目描述
给定一个整数数组,这个数组里只有一个数次出现了一次,其余数字出现了两次,求这个只出现一次的数字。
个人思路
以前在算法课上老师提到过这点。方法很巧妙,就是利用异或来计算就行。出现两次的所有数字按位异或的结果是 0,0 与出现一次的数字异或可以得到这个数字本身。
代码展示
int singleNumber(vector<int>& nums) {
int ans=0;
for(const int& num:nums){
ans=ans^num;
}
return ans;
}
总结
分治法将问题分解成子问题,递归地解决后合并,适用于具有相似结构的大问题。位运算是对二进制数的操作,如与、或、异或等,用于解决特定问题,如查找单独元素、交换值等。分治法解决大问题,位运算处理二进制操作。