1.数组列表中的最大距离
给定 m 个数组,每个数组都已经按照升序排好序了。
现在你需要从两个不同的数组中选择两个整数(每个数组选一个)并且计算它们的距离。两个整数 a 和 b 之间的距离定义为它们差的绝对值 |a-b| 。
一开始用第一个元素sort了,这样反而会出错,因为一个元素的数组可能是其他数组的中间值,这种情况他应该和左右两端都比较才对
直接挨个比较左右,同步更新preMax和preMin
class Solution {
public:
int maxDistance(vector<vector<int>>& arrays) {
int preMin = arrays[0][0];
int preMax = arrays[0].back();
int ans = INT_MIN;
for(int i = 1; i < arrays.size(); i ++){
ans = max(ans, arrays[i].back() - preMin);
ans = max(ans, preMax - arrays[i][0]);
preMin = min(preMin, arrays[i][0]);
preMax = max(preMax, arrays[i].back());
}
return ans;
}
};
2.字符串的左右移
给定一个包含小写英文字母的字符串 s 以及一个矩阵 shift,其中 shift[i] = [direction, amount]:
- direction 可以为 0 (表示左移)或 1 (表示右移)。
- amount 表示 s 左右移的位数。
- 左移 1 位表示移除 s 的第一个字符,并将该字符插入到 s 的结尾。
- 类似地,右移 1 位表示移除 s 的最后一个字符,并将该字符插入到 s 的开头。
对这个字符串进行所有操作后,返回最终结果。
输入:s = “abc”, shift = [[0,1],[1,2]]
输出:“cab”
解释:
[0,1] 表示左移 1 位。 “abc” -> “bca”
[1,2] 表示右移 2 位。 “bca” -> “cab”
始终没有别人的代码优雅…
统一操作符之后用substr
其中s.substr(n - k)是取s从下标n-k开始一直到末尾的子串
class Solution {
public:
string stringShift(string s, vector<vector<int>>& shift) {
int k = 0;
for (auto& v: shift) {
if (v[0] == 0) k -= v[1];
else k += v[1];
}
int n = s.size();
k %= n;
if (k < 0) k += n;
return s.substr(n - k) + s.substr(0, n - k);
}
};
3.相隔为1的编辑距离
可以插入,删除和替换,限制只能一次使得s==t,少一次都不行
所以注意sn == tn的情况,return的是flag,因为如果是true的话,flag一定是变化过一次的!
class Solution {
public:
bool isOneInsert(string shorter, string longer){
int sn = shorter.size();
int ln = longer.size();
int index1 = 0, index2 = 0;
while(index1 < sn && index2 < ln){
if(shorter[index1] == longer[index2]){
index1++;
}
index2++;
if(index2 - index1 > 1) return false;
}
return true;
}
bool isOneEditDistance(string s, string t) {
int sn = s.size();
int tn = t.size();
if(sn - tn == 1){
return isOneInsert(t, s);
}
else if(tn - sn == 1){
return isOneInsert(s, t);
}
else if(tn == sn){
bool flag = false;
for(int i = 0; i < sn; i ++){
if(s[i] != t[i]){
if(!flag){
flag = true;
}else{
return false;
}
}
}
return flag;
}
else return false;
}
};
4.形成字符串的最短路径
在这个问题中,我们得到了两个字符串,source 和 target。**我们需要用 source 最小数量的子 序列,让它们连起来等于 target。**如果无法做到,请返回 -1。
贪心
class Solution {
public:
int shortestWay(string source, string target) {
int ans = 0, i = 0, j;
// 外部循环,直到目标字符串的指针 `i` 遍历完 `target` 字符串
while(i < target.size()){
// 保存当前的 `i` 位置,方便后续判断是否有无法匹配的字符
j = i;
// 遍历 `source` 字符串以匹配 `target` 中的字符
for(auto &e : source){
// 如果 `source` 当前字符 `e` 和 `target[i]` 相等
if(e == target[i]) i ++; // 匹配到字符,`i` 向前移动,指向 `target` 的下一个字符
}
// 如果 `i` 没有前进,说明在 `source` 中找不到当前的 `target[i]` 字符
if(i == j) return -1;
ans++;
}
return ans;
}
};
5.连接二进制表示可形成的最大数值
给你一个长度为 3 的整数数组 nums。
现以某种顺序 连接 数组 nums 中所有元素的 二进制表示 ,请你返回可以由这种方法形成的 最大 数值。
注意 任何数字的二进制表示 不含 前导零。
class Solution {
public:
int f(int a, int b, int c){
vector<int> res;
while(a){
res.push_back(a & 1);
a /= 2;
}
while(b){
res.push_back(b & 1);
b /= 2;
}
while(c){
res.push_back(c & 1);
c /= 2;
}
reverse(res.begin(), res.end());//res是倒序存的!!
int ans = 0;
int n = res.size();
for(int i = res.size() - 1; i >= 0; i --){
if(res[i] == 1) ans += pow(2, res.size() - i - 1);
}
return ans;
}
int maxGoodNumber(vector<int>& nums) {
int m = 0;
m = max(m, f(nums[0], nums[1], nums[2]));
m = max(m, f(nums[0], nums[2], nums[1]));
m = max(m, f(nums[1], nums[0], nums[2]));
m = max(m, f(nums[1], nums[2], nums[0]));
m = max(m, f(nums[2], nums[0], nums[1]));
m = max(m, f(nums[2], nums[1], nums[0]));
return m;
}
};