首页 > 其他分享 >Leetcode weekly contest 312

Leetcode weekly contest 312

时间:2022-09-25 20:47:05浏览次数:76  
标签:idx nums int 312 contest ++ vector Leetcode size

Leetcode weekly conetest 312

1.按身高排序

解法: 直接利用STL中的sort来自定义排序规则即可。
Tag: 自定义排序

Code:


class Solution {
public:
    vector<string> sortPeople(vector<string>& names, vector<int>& heights) {
        vector<pair<string, int>> cnt;
        vector<string> res;
        for(int i = 0; i < names.size(); ++i) {
            cnt.push_back(make_pair(names[i], heights[i]));
        }
        auto cmp = [&](const pair<string, int>& a, const pair<string, int>& b) {
            return a.second > b.second;
        };
        sort(cnt.begin(), cnt.end(), cmp);
        for(auto&& [name, height] : cnt) {
            res.push_back(name);
        }
        return res;
    }
};

2.按位与最大的最长子数组

解法:这道题最重要的一个观察点就是,a & b < min(a, b), 也就是说任何数与其他数进行按位与操作,其值绝不会变大,因此这道题的最终答案就是最大数字的最长连续出现次数。
Tag: 脑筋急转弯, 位运算

Code:

class Solution {
public:
    int longestSubarray(vector<int>& nums) {
        int max_num = *max_element(nums.begin(), nums.end());
        int ans = 1;
        for(int i = 0; i < nums.size(); ++i) {
            // 利用双指针来进行记录
            if(nums[i] == max_num) {
                int fast = i;
                while(fast < nums.size() && nums[fast] == nums[i]) {
                    ++fast;
                }
                ans = max(ans, fast - i);
                i = fast;
            }
        }
        return ans;
    }
};

3.找到所有好下标

解法:这道题首先能想到一个简单的暴力解法,即在每个候选点都去看它的前k个字符以及后k个字符是否满足条件,但是这么做的问题在于,随着候选点不断前进,我们的候选区间其实并没有变化太多,但是却要从头开始遍历,这毫无疑问造成了许多重复计算。所以我们可以考虑用动态规划来降低整个计算的复杂度,我们预处理出以每个字符结尾的前缀个数和后缀个数,并在计算中加以利用。

Tag: 前缀和,后缀和,以及动态规划

Code:

class Solution {
public:
    vector<int> goodIndices(vector<int>& nums, int k) {
        vector<int> prefix(nums.size()), postfix(nums.size());
        vector<int> ans;
        prefix[0] = 1;
        for(int i = 1; i < nums.size(); ++i) {
            if(nums[i] <= nums[i - 1]) {
                prefix[i] = prefix[i - 1] + 1; 
            } else {
                prefix[i] = 1;
            }
        }
        postfix[nums.size() - 1] = 1;
        for(int i = nums.size() - 2; i >= 0; --i) {
            if(nums[i] <= nums[i + 1]) {
                postfix[i] = postfix[i + 1] + 1;
            } else {
                postfix[i] = 1;
            }
        }
        for(int i = k; i < nums.size() - k; ++i) {
            if(prefix[i - 1] >= k && postfix[i + 1] >= k) {
                ans.push_back(i);
            }
        }
        return ans;
    }
};

4.好路径的个数

解法: 先按照权值进行排序,这样的话我们就可以将值相同的节点打包在一起进行处理,并且利用并查集来进行合并以及查询点与点之间的连通性。

Tag: 并查集

Code:

class Solution {
private:
    vector<int> parent;
    unordered_map<int,vector<int>> graph;
public:
    // C++ Version
    size_t find(size_t x) {
        return parent[x] == x ? x : parent[x] = find(parent[x]);
    }

    void unite(int x, int y) {
        parent[find(x)] = find(y);
    }

    int numberOfGoodPaths(vector<int>& vals, vector<vector<int>>& edges) {
        auto len = vals.size();
        parent.resize(len);
        vector<int> idx(len);
        int ans = 0;
        for(auto&& edge : edges) {
            int from = edge[0], to = edge[1];
            graph[from].push_back(to);
            graph[to].push_back(from);
        }
        for(size_t i = 0; i < vals.size(); ++i) {
            parent[i] = i, idx[i] = i;
        }
        auto cmp = [&](int i, int j) {
            return vals[i] < vals[j];
        };
        sort(idx.begin(), idx.end(), cmp);
        for(int left = 0; left < idx.size(); ++left) {
            int right = left + 1;

            while(right < idx.size() && vals[idx[left]] == vals[idx[right]]) {
                ++right;
            }
            unordered_map<int, int> cnt;
            for(int k = left; k < right; ++k) {
                int target_node = idx[k];
                for(auto&& next : graph[target_node]) {
                    if(vals[next] <= vals[target_node]) {
                        unite(target_node, next);
                    }
                }
            }
            for(int k = left; k < right; ++k) {
                cnt[find(idx[k])]++;
            }

            for(auto&& [key, value] : cnt) {
                ans += value;
                if(value != 1) {
                    ans += value * (value - 1) / 2;
                }
            }

            left = right - 1;
        }
        return ans;
    }
};

标签:idx,nums,int,312,contest,++,vector,Leetcode,size
From: https://www.cnblogs.com/halftheworldaway/p/16728802.html

相关文章

  • LeetCode2096 从二叉树一个节点到另一个节点每一步的方向
    LeetCode2096从二叉树一个节点到另一个节点每一步的方向最近公共祖先的变形题.#Definitionforabinarytreenode.#classTreeNode:#def__init__(self,val......
  • 代码随想录 两两交换链表中的节点(LeetCode 24), 删除链表的倒数第N个节点(LeetCode 1
    两两交换链表中的节点题目给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。题目链接示例:题解对于奇数个节点,最后一个节点不交换。结束条件:对于奇数个节......
  • LeetCode 1382. Balance a Binary Search Tree
    原题链接在这里:https://leetcode.com/problems/balance-a-binary-search-tree/题目:Giventhe root ofabinarysearchtree,return a balanced binarysearchtre......
  • 第312场周赛
    T1:简单排序,sort一下即可T2:寻找连续子数组按位与值最大前提下,最长长度。非常不明显,最大按位与就是最大值,则最长长度则连续最大值的长度最大值(md仔细分析呀)T3:寻找下标满......
  • LeetCode 239. 滑动窗口最大值
    终于做了一道Hard...依旧是感觉差一点做出来,哎参考随想录思路题目给你一个整数数组nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到......
  • LeetCode 365. Water and Jug Problem
    原题链接在这里:https://leetcode.com/problems/water-and-jug-problem/题目:Youaregiventwojugswithcapacities jug1Capacity and jug2Capacity liters.There......
  • 代码随想录 链表理论基础, 移除链表元素(LeetCode 203), 设计链表(LeetCode 707)及翻转
    链表理论基础链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意......
  • leetcode python 解题模板
    一般的题classSolution(object):defletterCombinations(self,digits):""":typedigits:str:rtype:List[str]"""......
  • LeetCode - 数组的改变和移动
    1.数组的改变和移动总结1.1数组的改变数组在内存中是一块连续的内存空间,我们可以直接通过下标进行访问,并进行修改。在Java中,对于List类型来说,我们可以通过set(idx,el......
  • AtCoder Beginner Contest 270
    咕咕咕。D-Stones冲了发贪心,然后WA。然后想了个DP,就令\(dp_{n,0/1}\)表示石头总数为\(n\)时,先手/后手最多能拿多少个石头,然后跑个\(O(nk)\)的DP就完事了。......