本场题题目不难,但是力求写出精简优雅的代码,还是有需要学习的地方的。
第一题
力扣
class Solution:
def cellsInRange(self, s: str) -> List[str]:
ans = []
a,b,c,d = s[0],s[1],s[3],s[4]
for i in range(ord(a), ord(c)+1):
for j in range(int(b),int(d)+1):
ans.append(chr(i)+str(j))
return ans
第二题:
力扣
AC代码:
class Solution {
public:
long long calc(long long l, long long r) {
if(l>r) return 0;
return (l+r)*(r-l+1)/2;
}
long long minimalKSum(vector<int>& nums, int k) {
sort(nums.begin(), nums.end());
long long ans = 0;
if(nums[0] - 1 >= k) {
return calc(1, k);
} else {
ans += calc(1, nums[0]-1);
k -= nums[0]-1;
}
for(int i = 1; i<nums.size(); i++) {
if(nums[i] - nums[i-1] <=1) continue;
if(nums[i] - nums[i-1] - 1 <= k) {
k -= nums[i] - nums[i-1] - 1;
ans += calc(nums[i-1]+1, nums[i]-1);
} else {
ans += calc(nums[i-1]+1, nums[i-1]+1+k-1);
k = 0;
break;
}
}
if(k>0) {
ans += calc(nums[nums.size()-1]+1, nums[nums.size()-1]+k);
}
return ans;
}
};
AC代码2:(哨兵是个好东西)
class Solution {
public:
long long calc(long long l, long long r) {
if(l>r) return 0;
return (l+r)*(r-l+1)/2;
}
long long minimalKSum(vector<int>& nums, int k) {
nums.push_back(0);nums.push_back(int(1e9) + 5000000);
sort(nums.begin(), nums.end());
long long ans = 0;
for(int i = 1; i<nums.size(); i++) {
if(nums[i] - nums[i-1] <=1) continue;
if(nums[i] - nums[i-1] - 1 <= k) {
k -= nums[i] - nums[i-1] - 1;
ans += calc(nums[i-1]+1, nums[i]-1);
} else {
ans += calc(nums[i-1]+1, nums[i-1]+1+k-1);
k = 0;
break;
}
}
return ans;
}
};
AC代码3:
只需要一次等差数列求和公式。先假设取1~K,其他时候遍历数组往后加就可以了。
第三题
力扣
解题报告:
我写的真的是垃圾代码, 首先最后一个for循环完全可以合并到第一个里面的。因为他是指针啊,只要new出来了,就算left和right是null也没关系的,直接修改就行。
并且,这题用python写是真的爽,dict能代替这里的一切。抽空改写成py。
而且其实这里用set也不是最优的,再加个vis数组不好吗?非要带个log。
不过我刚开始想的是直接把fa给改成map的,但是也不太容易写精简了,因为你要找出现过但没作为子节点出现的 那个节点。
AC代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int fa[100005];
TreeNode* tr[100005];
TreeNode* createBinaryTree(vector<vector<int>>& descriptions) {
set<int> ss;
for(int i = 0; i<descriptions.size(); i++) {
int f = descriptions[i][0];
int s = descriptions[i][1];
fa[s] = f;
ss.insert(s);ss.insert(f);
if(tr[s] == nullptr) tr[s] = new TreeNode(s);
if(tr[f] == nullptr) tr[f] = new TreeNode(f);
}
int root;
for(auto x : ss) {
if(fa[x] == 0) {
root = x;break;
}
}
for(int i = 0; i<descriptions.size(); i++) {
int f = descriptions[i][0];
int s = descriptions[i][1];
if(descriptions[i][2] == 1) tr[f]->left = tr[s];
else tr[f]->right = tr[s];
}
return tr[root];
}
};
第四题
力扣
解题报告:
刚开始没看题,没看到要找相邻的两个“非互质数”。想了半天也凑出来了这个“升级版”题目的解法,一会说。
但是这题要是相邻的话,其实就简化很多了。
相邻的问题可以考虑栈做就行了。(就跟括号匹配之类的一样)
AC代码:
class Solution {
public:
long long gcd(long long a, long long b) {
return b==0?a:gcd(b,a%b);
}
long long lcm(long long a, long long b) {
return a*b/gcd(a,b);
}
vector<int> replaceNonCoprimes(vector<int>& nums) {
stack<int> sk;
sk.push(nums[0]);
for(int i = 1; i<nums.size(); i++) {
sk.push(nums[i]);
int t1 = sk.top();sk.pop();
int t2 = sk.top();sk.pop();
int flag = 0;
while(gcd(t1, t2) != 1) {
sk.push(lcm(t1, t2));
if(sk.size() <= 1) {
flag = 1;
break;
}
t1 = sk.top();sk.pop();
t2 = sk.top();sk.pop();
}
if(flag == 0) {
sk.push(t2);sk.push(t1);
}
}
vector<int> ans;
while(sk.size()) {
int x = sk.top();
ans.push_back(x);sk.pop();
}
reverse(ans.begin(), ans.end());
return ans;
}
};
这题1WA了因为sk.size()<=1的时候break了但是忘把取出来的元素再push进去了。
然后2WA是这么写的:其实是只改了再外面pop的情况。应该再想想,还有没有类似的情况会导致pop后忘记push。这样就会发现while里面也有。。然后就可以一次性改对了。
//2WA的部分代码
for(int i = 1; i<nums.size(); i++) {
sk.push(nums[i]);
int t1 = sk.top();sk.pop();
int t2 = sk.top();sk.pop();
if(gcd(t1, t2) != 1) {
while(gcd(t1, t2) != 1) {
sk.push(int(lcm(t1, t2)));
if(sk.size() <= 1) {
break;
}
t1 = sk.top();sk.pop();
t2 = sk.top();sk.pop();
}
} else {
sk.push(t2);sk.push(t1);
}
}
这题也写丑了。对于stack的问题其实完全可以用vector去写的,这样一来最后不用出栈再reverse一遍,二来不用再繁琐的每次sk.top()sk.pop(),直接取v[v.size()-1]和v[v.size()-2]就行了,这样也不用if flag==0 再push进去了,真是太丑了。看看人家怎么写的。
class Solution {
public:
int gcd(int x, int y) { return y ? gcd(y, x % y) : x; }
vector<int> replaceNonCoprimes(vector<int>& nums) {
int n = nums.size();
vector<int> ans;
for (int i = 0; i < n; ++i) {
int t = nums[i];
while (!ans.empty() && gcd(t, ans.back()) > 1) {
t = t / gcd(t, ans.back()) * ans.back();
ans.pop_back();
}
ans.push_back(t);
}
return ans;
}
};