力扣周赛139
1、字符串的最大公因子
简单逻辑题,辗转相减(我自创的,哈哈),刚开始思路有问题但是能过(可见力扣样例有多水),后来改了。
注意:两个思路的区别在于,错的代码是直接减,正确的是判断之后再再减。
- 思路有问题但是过了的代码
class Solution {
public:
string gcdOfStrings(string s, string t) {
//用判断s和t是否相等,如果不等就从长字符串中删去短字符串长度的内容,从头开始,或者从尾开始都行。
//比如给出s=abcdef,t=asd,判断s和t是否相等,不相等就删除s最后的三个字符,继续判断
//这里如果是abcd和ab的时候,会输出ab,但是答案是空串,我也不知道为什么过了
while (s != t && s.size()!=0 && t.size()!=0) {
//如果有一个字符串长度为0,就跳出。
if (s.size() > t.size()) {
s.erase(s.end() - t.size(), s.end());
}
else {
t.erase(t.end() - s.size(), t.end());
}
}
string ans;
if (s.size() == 0 || t.size() == 0) {
ans = "";
}
else {
ans = s;
}
return ans;
}
};
- 这个是正确的已过代码:
class Solution {
public:
string gcdOfStrings(string s, string t) {
while (s != t && s.size()!=0 && t.size()!=0) {
if (s.size()<t.size()){
string kt=s;
s=t;
t=kt;
}
//让s的长度始终是最长的那个字符串
for(int i=0;i<t.size();i++){
if (s[i]!=t[i]){//如果有不相等的,说明答案就是空串,清空数据
s.clear();
t.clear();
break;
}
}
if (s.size()>0){
//如果s的长度大于0,说明符合条件,然后减去相等的部分,继续判断。
s.erase(s.begin(),s.begin()+t.size());
}
}
string ans;
if (s.size() == 0 || t.size() == 0) {
ans = "";
}
else {
ans = s;
}
return ans;
}
};
2、按列翻转得到最大值等行数
简单逻辑题,正常做很难想,换个思路会比较好。
有个概念,需要提前说一下,反面:10010的反面是01101,就是把1全换成0,把0全换成1。
接下来举个例子:
a、11000
b、11000
c、11100
d、11100
e、00011
f、10101
g、11111
给出以上数据,两两比较,找出相等的或者互为反面的,放在一组。
可以得出:
a,b一组;;记为第一组
c、d、e一组;;记为第二组
f一组;;记为第三组
g一组;;记为第四组
由题意得:不管怎么翻转,都只能实现其中一组的数据,比如说,我们实现了第一组的数据(翻转一二列),a行和b行符合条件,除了a和b,其余所有行都不符合条件。也就是说我们需要找到组内元素的最大值,就是答案。(注意:)
class Solution {
public:
int maxEqualRowsAfterFlips(vector<vector<int>>& m) {
vector <string>s1;
vector <string>s2;
for (int i = 0; i < m.size(); i++) {
string t1;
string t2;
for (int j = 0; j < m[i].size(); j++) {
if (m[i][j]) {
t1.push_back('1');
t2.push_back('0');
}
else {
t1.push_back('0');
t2.push_back('1');
}
}
s1.push_back(t1);
s2.push_back(t2);
}
//第一步将所有的一维数组改成string型,并且记录反面。
int num[300] = { 0 };//记录与第i行相等,或者反面相等的有几行
for (int i = 0; i < s1.size(); i++) {
for (int j = i + 1; j < s1.size(); j++) {
//两两进行比较,如果相等,或者等于反面,就让num加一。
if (s1[i] == s1[j] || s1[i] == s2[j]) {
num[i]++;
}
}
}
int ans = -1;
for (int i = 0; i < 300; i++) {
ans = ans > num[i] ? ans : num[i];
}
return ans+1;//最后需要加上自己。
}
};
3、负二进制数相加
简单逻辑题,在做之前,我们需要推一个公式:
(
−
2
)
n
+
1
+
(
−
2
)
n
+
(
−
2
)
n
=
(
−
2
)
∗
(
−
2
)
n
+
(
−
2
)
n
+
(
−
2
)
n
=
0
(-2)^{n+1}+(-2)^{n}+(-2)^{n}=(-2)*(-2)^{n}+(-2)^{n}+(-2)^{n}=0
(−2)n+1+(−2)n+(−2)n=(−2)∗(−2)n+(−2)n+(−2)n=0这个说明什么呢:
说明对于两个相邻的位,低位加二,高位加一对最后的和并没有影响
比如说:
10010
12110
10031
这三个都是相等的。
然后就好做了
题解:
给出vector s和vector t。s:100100,,t:100100
将s,t翻转,s=001001,,t=001001
将t的每个数字都加到s上,s=002002
在s后面加上21(防止溢出);s=00200221
然后从第一个数字遍历s,
如果s[i]小于零,s[i]+=2,s[i+1]++;
如果s[i]大于一,s[i]-=2,s[i+1]–;
class Solution {
public:
vector<int> addNegabinary(vector<int>& s, vector<int>& t) {
reverse(s.begin(), s.end());
reverse(t.begin(), t.end());
if (s.size() < t.size()) {
vector <int>st;
st = s;
s = t;
t = st;
}
//先将s和t翻转,s长度>t的长度
for (int i = 0; i < t.size(); i++) {
s[i] += t[i];
}
s.push_back(2);
s.push_back(1);
for (int i=0;i<s.size()-1;i++){
if (s[i]>1){
s[i]-=2;
s[i+1]--;
}
if (s[i]<0){
s[i+1]++;
s[i]+=2;
}
}
while (s.back() == 0 && s.size()>1) {
//最后将前置零删除,但是s数组必须有数据。
s.pop_back();
}
reverse(s.begin(),s.end());//翻转
return s;
}
};
第四题嘛,自己太菜,没做出来(手动狗头)。