LeetCode单周赛第320场 && AcWing周赛第78场总结

1. LeetCode单周赛第320场

1.1 数组中不等三元组的数目

1.1.1 原题链接:力扣icon-default.png?t=M85Bhttps://leetcode.cn/problems/number-of-unequal-triplets-in-array/

1.1.2 解题思路:

        暴力遍历咯。

1.1.3 代码:

class Solution {
public:
    int unequalTriplets(vector<int>& nums) {
        int n = nums.size();
        
        int res = 0;
        for(int i = 0; i < n; i ++ ) 
            for(int j = i + 1; j < n; j ++ ) 
                for(int k = j + 1; k < n; k ++ ) 
                    if(nums[i] != nums[j] && nums[i] != nums[k] && nums[j] != nums[k]) 
                        res ++;
        
        return res;
    }
};

1.2 二叉搜索树最近节点查询

1.2.1 原题链接:力扣icon-default.png?t=M85Bhttps://leetcode.cn/problems/closest-nodes-queries-in-a-binary-search-tree/

1.2.2 解题思路:

        1、先把树种的元素存到数组中;

        2、把数组中的元素排序,然后二分找满足要求的元素。

1.2.3 代码:

/**
 * 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:
    void tra(TreeNode* root, vector<int>& t)
    {
        if(root == nullptr) return;
        t.push_back(root->val);
        tra(root->left, t);
        tra(root->right, t);

    }
    vector<vector<int>> closestNodes(TreeNode* root, vector<int>& queries) {
        vector<vector<int>> res;
        
        vector<int> tmp;
        tra(root, tmp);
        
        sort(tmp.begin(), tmp.end());
        int n = tmp.size();
        for(auto& x: queries) {
            int a, b;
            int l = 0, r = n - 1;
            while(l < r) {
                int mid = l + r + 1 >> 1;
                if(tmp[mid] > x) r = mid - 1;
                else l = mid;
            }
            
            if(tmp[l] <= x) a = tmp[l];
            else a = -1;
            
            l = 0, r = n - 1;
            while(l < r) {
                int mid = l + r >> 1;
                if(tmp[mid] < x) l = mid + 1;
                else r = mid;
            }
            
            if(tmp[l] >= x) b = tmp[l];
            else b = -1;
            
            res.push_back({a, b});
        }
        return res;
    }
};

1.3 到达首都最少油耗

1.3.1 原题链接:力扣icon-default.png?t=M85Bhttps://leetcode.cn/problems/minimum-fuel-cost-to-report-to-the-capital/

1.3.2 解题思路:

        以 0 为根,统计每个子树中节点的个数cur,那么每个子树需要的车的数量就是 cur / seats 向上取整。

1.3.3 代码:

#define N 100010
#define M 200010

int h[N], e[M], ne[M], idx;

typedef long long ll;

class Solution {
public:
    ll ans = 0;
    void add(int a, int b)
    {
        e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
    }

    ll dfs(int u, int father, int seats) 
    {
        ll cur = 1;
        for(int i = h[u]; i != -1; i = ne[i]){
            int j = e[i];
            if(j != father) {
                cur += dfs(j, u, seats);
            }
        }

        if(u != 0) {
            ans += (cur + seats - 1) / seats;  //向上取整
        }
        return cur;
    }

    long long minimumFuelCost(vector<vector<int>>& roads, int seats) {
        memset(h, -1, sizeof h);
        idx = 0;
        for(auto& road: roads) {
            add(road[0], road[1]);
            add(road[1], road[0]);
        }
        
        dfs(0, -1, seats);
        return ans; 
    }
};

2.AcWing周赛第78场

2.1 商品种类

2.1.1 原题链接:4719. 商品种类 - AcWing题库

2.1.2 解题思路:

        使用set将产品的产地+名称存储到set中,最后返回set的大小即可。

2.1.3 代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_set>

using namespace std;

int main()
{
    int n;
    cin >> n;
    
    unordered_set<string> st;
    for(int i = 0; i < n; i ++ ) {
        string a, b;
        cin >> a >> b;
        
        st.insert(a + ' ' + b);
    }
    
    cout << st.size() << endl;
    return 0;
}

2.2 字符串

2.2.1 原题链接:4720. 字符串 - AcWing题库

2.2.2 解题思路:

        把字符串 s 中的字符一个一个存到答案字符串 res 中,若与 res 中的最后一个字符相同,则把字符串 res 中的最后一个字符删去,反之,则加入到 res 中。最后输出 res 即可。

2.2.3 代码:

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

int main()
{
    string s;
    cin >> s;
    
    string res;
    for(auto c: s) {
        if(res.size() && res.back() == c) res.pop_back();
        else res += c;
    }
    
    cout << res << endl;
    return 0;
}

2.3 排队

2.3.1 原题链接:4721. 排队 - AcWing题库

2.3.2 解题思路:

        1、用单调队列+二分的思路解决此问题;

        2、从后往前遍历身高,栈里存的是对应身高的下标,每次对栈内下标二分找到比自身矮的最右侧一个人的位置;

        3、对于栈内元素的维护,具有单调性,因为例如,对于寻找比 a[k] (k > i && k > j)的矮的最右侧的一位在哪,如果a[i], a[j]均小于a[k],且 i < j,那么,a[i]就没有存在必要了。

2.3.3 代码:

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long ll;
const int N = 1e5 + 10;

int h[N], stk[N];
int n;
int ans[N];

int main()
{
    scanf("%d", &n);
    for(int i = 0; i < n; i ++ ) scanf("%d", &h[i]);
    
    int top = 0;
    for(int i = n - 1; i >= 0; i -- ) {
        if(!top || h[i] <= h[stk[top]]) ans[i] = -1;
        else {
            int l = 1, r = top;
            while(l < r) {
                int mid = l + r >> 1;
                if(h[stk[mid]] < h[i]) r = mid;
                else l = mid + 1;
            }
            ans[i] = stk[r] - i - 1;
        }
        
        if(!top || h[i] < h[stk[top]]) stk[++ top] = i;
    }
    
    for(int i = 0; i < n; i ++ ) 
        printf("%d ", ans[i]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值