0
点赞
收藏
分享

微信扫一扫

【LeetCode】第283场周赛题解

狐沐说 2022-03-11 阅读 125

本场题题目不难,但是力求写出精简优雅的代码,还是有需要学习的地方的。

第一题

力扣

 

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;
    }
};
举报

相关推荐

0 条评论