当前位置:首页 > 编程笔记 > 正文
已解决

leetcode解题思路分析(一百五十一)1313 - 1319 题

来自网友在路上 172872提问 提问时间:2023-11-08 22:53:55阅读次数: 72

最佳答案 问答题库728位专家为你答疑解惑

  1. 解压缩编码列表
    给你一个以行程长度编码压缩的整数列表 nums 。考虑每对相邻的两个元素 [freq, val] = [nums[2i], nums[2i+1]] (其中 i >= 0 ),每一对都表示解压后子列表中有 freq 个值为 val 的元素,你需要从左到右连接所有子列表以生成解压后的列表。请你返回解压后的列表
class Solution {
public:vector<int> decompressRLElist(vector<int>& nums) {vector<int> ret;int         nSize = nums.size();for (int i = 0; i < nSize;){int nFreq = nums[i];int nVal  = nums[i + 1];while (nFreq){ret.push_back(nVal);nFreq--;}i += 2;}return ret;}
};
  1. 矩阵区域和
    给你一个 m x n 的矩阵 mat 和一个整数 k ,请你返回一个矩阵 answer ,其中每个 answer[i][j] 是所有满足下述条件的元素 mat[r][c] 的和:
    i - k <= r <= i + k,
    j - k <= c <= j + k 且
    (r, c) 在矩阵内。

存储mat的二位前缀和,然后筛选符合条件的相加即可。

class Solution {
public:int get(const vector<vector<int>>& pre, int m, int n, int x, int y) {x = max(min(x, m), 0);y = max(min(y, n), 0);return pre[x][y];}vector<vector<int>> matrixBlockSum(vector<vector<int>>& mat, int K) {int m = mat.size(), n = mat[0].size();vector<vector<int>> P(m + 1, vector<int>(n + 1));for (int i = 1; i <= m; ++i) {for (int j = 1; j <= n; ++j) {P[i][j] = P[i - 1][j] + P[i][j - 1] - P[i - 1][j - 1] + mat[i - 1][j - 1];}}vector<vector<int>> ans(m, vector<int>(n));for (int i = 0; i < m; ++i) {for (int j = 0; j < n; ++j) {ans[i][j] = get(P, m, n, i + K + 1, j + K + 1) - get(P, m, n, i - K, j + K + 1) - get(P, m, n, i + K + 1, j - K) + get(P, m, n, i - K, j - K);}}return ans;}
};
  1. 祖父节点值为偶数的节点和
    给你一棵二叉树,请你返回满足以下条件的所有节点的值之和:该节点的祖父节点的值为偶数。(一个节点的祖父节点是指该节点的父节点的父节点。)如果不存在祖父节点值为偶数的节点,那么返回 0 。

挨个遍历并且保存其孙子的值即可

/*** 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 sumEvenGrandparent(TreeNode* root) {queue<TreeNode*> q;q.push(root);int ans = 0;while (!q.empty()) {TreeNode* node = q.front();q.pop();if (node->val % 2 == 0) {if (node->left) {if (node->left->left) {ans += node->left->left->val;}if (node->left->right) {ans += node->left->right->val;}}if (node->right) {if (node->right->left) {ans += node->right->left->val;}if (node->right->right) {ans += node->right->right->val;}}}if (node->left) {q.push(node->left);}if (node->right) {q.push(node->right);}}return ans;}
};
  1. 不同的循环子字符串
    给你一个字符串 text ,请你返回满足下述条件的 不同 非空子字符串的数目:
    可以写成某个字符串与其自身相连接的形式(即,可以写为 a + a,其中 a 是某个字符串)。
    例如,abcabc 就是 abc 和它自身连接形成的。

前缀和+滚动哈希,将字符串视作多进制的一串数字进行处理。

using LL = long long;class Solution {
private:constexpr static int mod = (int)1e9 + 7;public:int gethash(const vector<int>& pre, const vector<int>& mul, int l, int r) {return (pre[r + 1] - (LL)pre[l] * mul[r - l + 1] % mod + mod) % mod;}int distinctEchoSubstrings(string text) {int n = text.size();int base = 31;vector<int> pre(n + 1), mul(n + 1);pre[0] = 0;mul[0] = 1;for (int i = 1; i <= n; ++i) {pre[i] = ((LL)pre[i - 1] * base + text[i - 1]) % mod;mul[i] = (LL)mul[i - 1] * base % mod;}unordered_set<int> seen[n];int ans = 0;for (int i = 0; i < n; ++i) {for (int j = i + 1; j < n; ++j) {int l = j - i;if (j + l <= n) {int hash_left = gethash(pre, mul, i, j - 1);if (!seen[l - 1].count(hash_left) && hash_left == gethash(pre, mul, j, j + l - 1)) {++ans;seen[l - 1].insert(hash_left);}}}}return ans;}
};
  1. 将整数转换为两个无零整数的和
    给你一个整数 n,请你返回一个 由两个整数组成的列表 [A, B],满足:
    A 和 B 都是无零整数
    A + B = n
    题目数据保证至少有一个有效的解决方案。
    如果存在多个有效解决方案,你可以返回其中任意一个。
class Solution {
public:vector<int> getNoZeroIntegers(int n) {for (int A = 1; A < n; ++A) {int B = n - A;if ((to_string(A) + to_string(B)).find('0') == string::npos) {return {A, B};}}return {};}
};
  1. 或运算的最小翻转次数
    给你三个正整数 a、b 和 c。
    你可以对 a 和 b 的二进制表示进行位翻转操作,返回能够使按位或运算 a OR b == c 成立的最小翻转次数。
    「位翻转操作」是指将一个数的二进制表示任何单个位上的 1 变成 0 或者 0 变成 1 。

c的某位为1,则a/b有一个为1即可,如果a+b为0则翻转1次否则不用翻转;c的某位为0,则a和b必须该位都为0,所以翻转次数刚好是a+b的值

class Solution {
public:int minFlips(int a, int b, int c) {int ans = 0;for (int i = 0; i < 31; ++i) {int bit_a = (a >> i) & 1;int bit_b = (b >> i) & 1;int bit_c = (c >> i) & 1;if (bit_c == 0) {ans += bit_a + bit_b;}else {ans += (bit_a + bit_b == 0);}}return ans;}
};
  1. 连通网络的操作次数
    用以太网线缆将 n 台计算机连接成一个网络,计算机的编号从 0 到 n-1。线缆用 connections 表示,其中 connections[i] = [a, b] 连接了计算机 a 和 b。网络中的任何一台计算机都可以通过网络直接或者间接访问同一个网络中其他任意一台计算机。给你这个计算机网络的初始布线 connections,你可以拔开任意两台直连计算机之间的线缆,并用它连接一对未直连的计算机。请你计算并返回使所有计算机都连通所需的最少操作次数。如果不可能,则返回 -1 。

并查集求解模板题。

// 并查集模板
class UnionFind {
public:vector<int> parent;vector<int> size;int n;// 当前连通分量数目int setCount;public:UnionFind(int _n): n(_n), setCount(_n), parent(_n), size(_n, 1) {iota(parent.begin(), parent.end(), 0);}int findset(int x) {return parent[x] == x ? x : parent[x] = findset(parent[x]);}bool unite(int x, int y) {x = findset(x);y = findset(y);if (x == y) {return false;}if (size[x] < size[y]) {swap(x, y);}parent[y] = x;size[x] += size[y];--setCount;return true;}bool connected(int x, int y) {x = findset(x);y = findset(y);return x == y;}
};class Solution {
public:int makeConnected(int n, vector<vector<int>>& connections) {if (connections.size() < n - 1) {return -1;}UnionFind uf(n);for (const auto& conn: connections) {uf.unite(conn[0], conn[1]);}return uf.setCount - 1;}
};
查看全文

99%的人还看了

猜你感兴趣

版权申明

本文"leetcode解题思路分析(一百五十一)1313 - 1319 题":http://eshow365.cn/6-35639-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!