力扣OJ(1601-2000)

目录

1602. 找到二叉树中最近的右侧节点

1611. 使整数变为 0 的最少操作次数

1612. 检查两棵二叉表达式树是否等价

1631. 最小体力消耗路径

1632. 矩阵转换后的秩

1634. 求两个多项式链表的和

1644. 二叉树的最近公共祖先 II

1650. 二叉树的最近公共祖先 III

1658. 将 x 减到 0 的最小操作数

1662. 检查两个字符串数组是否相等

1663. 具有给定数值的最小字符串

1664. 生成平衡数组的方案数

1666. 改变二叉树的根节点

1668. 最大重复子字符串

1669. 合并两个链表

1676. 二叉树的最近公共祖先 IV

1682. 最长回文子序列 II

1684. 统计一致字符串的数目

1696. 跳跃游戏 VI

1697. 检查边长度限制的路径是否存在

1704. 判断字符串的两半是否相似

1724. 检查边长度限制的路径是否存在 II

1732. 找到最高海拔

1735. 生成乘积数组的方案数

1740. 找到二叉树中的距离

1742. 盒子中小球的最大数量

1752. 检查数组是否经排序和轮转得到

1768. 交替合并字符串

1773. 统计匹配检索规则的物品数量

1780. 判断一个数字是否可以表示成三的幂的和

1785. 构成特定和需要添加的最少元素

1796. 字符串中第二大的数字

1799. N 次操作后的最大分数和

1801. 积压订单中的订单总数

1802. 有界数组中指定下标处的最大值

1803. 统计异或值在范围内的数对有多少

1804. 实现 Trie (前缀树) II

1805. 字符串中不同整数的数目

1806. 还原排列的最少操作步数

1807. 替换字符串中的括号内容

1812. 判断国际象棋棋盘中一个格子的颜色

1813. 句子相似性 III

1814. 统计一个数组中好对子的数目

1815. 得到新鲜甜甜圈的最多组数

1817. 查找用户活跃分钟数

1819. 序列中不同最大公约数的数目

1822. 数组元素积的符号

1824. 最少侧跳次数(DP)

1825. 求出 MK 平均值

1827. 最少操作使数组递增

1828. 统计一个圆中点的数目

1835. 所有数对按位与结果的异或和

1862. 向下取整数对和

1863. 找出所有子集的异或总和再求和

1884. 鸡蛋掉落-两枚鸡蛋

1902. 给定二叉搜索树的插入顺序求深度

1908. Nim 游戏 II

1911. 最大子序列交替和

1922. 统计好数字的数目

1971. 寻找图中是否存在路径

1973. 值等于子节点值之和的节点数量

1979. 找出数组的最大公约数

1989. 捉迷藏中可捕获的最大人数

1992. 找到所有的农场组

1998. 数组的最大公因数排序

1999. 最小的仅由两个数组成的倍数


1602. 找到二叉树中最近的右侧节点

二叉树

1611. 使整数变为 0 的最少操作次数

九连环

1612. 检查两棵二叉表达式树是否等价

二叉树

1631. 最小体力消耗路径

BFS

1632. 矩阵转换后的秩

并查集

1634. 求两个多项式链表的和

单链表

1644. 二叉树的最近公共祖先 II

LCA

1650. 二叉树的最近公共祖先 III

LCA

1658. 将 x 减到 0 的最小操作数

搜索

1662. 检查两个字符串数组是否相等

水题

1663. 具有给定数值的最小字符串

水题

1664. 生成平衡数组的方案数

水题

1666. 改变二叉树的根节点

二叉树

1668. 最大重复子字符串

KMP

1669. 合并两个链表

链表

1676. 二叉树的最近公共祖先 IV

LCA

1682. 最长回文子序列 II

高维DP

1684. 统计一致字符串的数目

水题

1696. 跳跃游戏 VI

数列DP

1697. 检查边长度限制的路径是否存在

并查集

1704. 判断字符串的两半是否相似

水题

1724. 检查边长度限制的路径是否存在 II

并查集

1732. 找到最高海拔

水题

1735. 生成乘积数组的方案数

组合数

1740. 找到二叉树中的距离

二叉树

1742. 盒子中小球的最大数量

水题

1752. 检查数组是否经排序和轮转得到

水题

1768. 交替合并字符串

水题

1773. 统计匹配检索规则的物品数量

给你一个数组 items ,其中 items[i] = [typei, colori, namei] ,描述第 i 件物品的类型、颜色以及名称。

另给你一条由两个字符串 ruleKey 和 ruleValue 表示的检索规则。

如果第 i 件物品能满足下述条件之一,则认为该物品与给定的检索规则 匹配 :

  • ruleKey == "type" 且 ruleValue == typei 。
  • ruleKey == "color" 且 ruleValue == colori 。
  • ruleKey == "name" 且 ruleValue == namei 。

统计并返回 匹配检索规则的物品数量 。

示例 1:

输入:items = [["phone","blue","pixel"],["computer","silver","lenovo"],["phone","gold","iphone"]], ruleKey = "color", ruleValue = "silver"
输出:1
解释:只有一件物品匹配检索规则,这件物品是 ["computer","silver","lenovo"] 。

示例 2:

输入:items = [["phone","blue","pixel"],["computer","silver","phone"],["phone","gold","iphone"]], ruleKey = "type", ruleValue = "phone"
输出:2
解释:只有两件物品匹配检索规则,这两件物品分别是 ["phone","blue","pixel"] 和 ["phone","gold","iphone"] 。注意,["computer","silver","phone"] 未匹配检索规则。

提示:

  • 1 <= items.length <= 104
  • 1 <= typei.length, colori.length, namei.length, ruleValue.length <= 10
  • ruleKey 等于 "type""color" 或 "name"
  • 所有字符串仅由小写字母组成
class Solution {
public:
	int countMatches(vector>& items, string ruleKey, string ruleValue) {
		int k = 0, ans = 0;
		if (ruleKey == "color")k = 1;
		if (ruleKey == "name")k = 2;
		for (auto& v : items)if (v[k] == ruleValue)ans++;
		return ans;
	}
};

1780. 判断一个数字是否可以表示成三的幂的和

数论

1785. 构成特定和需要添加的最少元素

给你一个整数数组 nums ,和两个整数 limit 与 goal 。数组 nums 有一条重要属性:abs(nums[i]) <= limit 。

返回使数组元素总和等于 goal 所需要向数组中添加的 最少元素数量 ,添加元素 不应改变 数组中 abs(nums[i]) <= limit 这一属性。

注意,如果 x >= 0 ,那么 abs(x) 等于 x ;否则,等于 -x 。

示例 1:

输入:nums = [1,-1,1], limit = 3, goal = -4
输出:2
解释:可以将 -2 和 -3 添加到数组中,数组的元素总和变为 1 - 1 + 1 - 2 - 3 = -4 。

示例 2:

输入:nums = [1,-10,9,1], limit = 100, goal = 0
输出:1

提示:

  • 1 <= nums.length <= 105
  • 1 <= limit <= 106
  • -limit <= nums[i] <= limit
  • -109 <= goal <= 109
class Solution {
public:
	int minElements(vector& nums, int limit, int goal) {
		return (abs(GetSum(nums) - goal) + limit - 1) / limit;
	}
};

1796. 字符串中第二大的数字

水题

1799. N 次操作后的最大分数和

状态压缩DP

1801. 积压订单中的订单总数

给你一个二维整数数组 orders ,其中每个 orders[i] = [pricei, amounti, orderTypei] 表示有 amounti 笔类型为 orderTypei 、价格为 pricei 的订单。

订单类型 orderTypei 可以分为两种:

0 表示这是一批采购订单 buy
1 表示这是一批销售订单 sell
注意,orders[i] 表示一批共计 amounti 笔的独立订单,这些订单的价格和类型相同。对于所有有效的 i ,由 orders[i] 表示的所有订单提交时间均早于 orders[i+1] 表示的所有订单。

存在由未执行订单组成的 积压订单 。积压订单最初是空的。提交订单时,会发生以下情况:

如果该订单是一笔采购订单 buy ,则可以查看积压订单中价格 最低 的销售订单 sell 。如果该销售订单 sell 的价格 低于或等于 当前采购订单 buy 的价格,则匹配并执行这两笔订单,并将销售订单 sell 从积压订单中删除。否则,采购订单 buy 将会添加到积压订单中。
反之亦然,如果该订单是一笔销售订单 sell ,则可以查看积压订单中价格 最高 的采购订单 buy 。如果该采购订单 buy 的价格 高于或等于 当前销售订单 sell 的价格,则匹配并执行这两笔订单,并将采购订单 buy 从积压订单中删除。否则,销售订单 sell 将会添加到积压订单中。
输入所有订单后,返回积压订单中的 订单总数 。由于数字可能很大,所以需要返回对 109 + 7 取余的结果。

示例 1:


输入:orders = [[10,5,0],[15,2,1],[25,1,1],[30,4,0]]
输出:6
解释:输入订单后会发生下述情况:
- 提交 5 笔采购订单,价格为 10 。没有销售订单,所以这 5 笔订单添加到积压订单中。
- 提交 2 笔销售订单,价格为 15 。没有采购订单的价格大于或等于 15 ,所以这 2 笔订单添加到积压订单中。
- 提交 1 笔销售订单,价格为 25 。没有采购订单的价格大于或等于 25 ,所以这 1 笔订单添加到积压订单中。
- 提交 4 笔采购订单,价格为 30 。前 2 笔采购订单与价格最低(价格为 15)的 2 笔销售订单匹配,从积压订单中删除这 2 笔销售订单。第 3 笔采购订单与价格最低的 1 笔销售订单匹配,销售订单价格为 25 ,从积压订单中删除这 1 笔销售订单。积压订单中不存在更多销售订单,所以第 4 笔采购订单需要添加到积压订单中。
最终,积压订单中有 5 笔价格为 10 的采购订单,和 1 笔价格为 30 的采购订单。所以积压订单中的订单总数为 6 。
示例 2:


输入:orders = [[7,1000000000,1],[15,3,0],[5,999999995,0],[5,1,1]]
输出:999999984
解释:输入订单后会发生下述情况:
- 提交 109 笔销售订单,价格为 7 。没有采购订单,所以这 109 笔订单添加到积压订单中。
- 提交 3 笔采购订单,价格为 15 。这些采购订单与价格最低(价格为 7 )的 3 笔销售订单匹配,从积压订单中删除这 3 笔销售订单。
- 提交 999999995 笔采购订单,价格为 5 。销售订单的最低价为 7 ,所以这 999999995 笔订单添加到积压订单中。
- 提交 1 笔销售订单,价格为 5 。这笔销售订单与价格最高(价格为 5 )的 1 笔采购订单匹配,从积压订单中删除这 1 笔采购订单。
最终,积压订单中有 (1000000000-3) 笔价格为 7 的销售订单,和 (999999995-1) 笔价格为 5 的采购订单。所以积压订单中的订单总数为 1999999991 ,等于 999999984 % (109 + 7) 。
 

提示:

1 <= orders.length <= 105
orders[i].length == 3
1 <= pricei, amounti <= 109
orderTypei 为 0 或 1

class Solution {
public:
	int getNumberOfBacklogOrders(vector>& orders) {
		long long ans = 0;
		priority_queue>q0, q1;
		for (auto vi : orders) {
			if (vi[2] == 0)q0.push(vi);
			else {
				vi[0] *= -1;
				q1.push(vi);
			}
			ans += vi[1];
			while (!q0.empty() && !q1.empty()) {
				if (q0.top()[0] + q1.top()[0] < 0)break;
				int m = min(q0.top()[1], q1.top()[1]);
				ans -= m * 2;
				auto v0 = q0.top(), v1 = q1.top();
				q0.pop(), q1.pop();
				v0[1] -= m, v1[1] -= m;
				if (v0[1])q0.push(v0);
				if (v1[1])q1.push(v1);
			}
		}
		return ans % 1000000007;
	}
};

1802. 有界数组中指定下标处的最大值

二分法

1803. 统计异或值在范围内的数对有多少

给你一个整数数组 nums (下标 从 0 开始 计数)以及两个整数:low 和 high ,请返回 漂亮数对 的数目。

漂亮数对 是一个形如 (i, j) 的数对,其中 0 <= i < j < nums.length 且 low <= (nums[i] XOR nums[j]) <= high 。

示例 1:

输入:nums = [1,4,2,7], low = 2, high = 6
输出:6
解释:所有漂亮数对 (i, j) 列出如下:
    - (0, 1): nums[0] XOR nums[1] = 5 
    - (0, 2): nums[0] XOR nums[2] = 3
    - (0, 3): nums[0] XOR nums[3] = 6
    - (1, 2): nums[1] XOR nums[2] = 6
    - (1, 3): nums[1] XOR nums[3] = 3
    - (2, 3): nums[2] XOR nums[3] = 5
示例 2:

输入:nums = [9,8,4,2,1], low = 5, high = 14
输出:8
解释:所有漂亮数对 (i, j) 列出如下:
​​​​​    - (0, 2): nums[0] XOR nums[2] = 13
    - (0, 3): nums[0] XOR nums[3] = 11
    - (0, 4): nums[0] XOR nums[4] = 8
    - (1, 2): nums[1] XOR nums[2] = 12
    - (1, 3): nums[1] XOR nums[3] = 10
    - (1, 4): nums[1] XOR nums[4] = 9
    - (2, 3): nums[2] XOR nums[3] = 6
    - (2, 4): nums[2] XOR nums[4] = 5
 

提示:

1 <= nums.length <= 2 * 104
1 <= nums[i] <= 2 * 104
1 <= low <= high <= 2 * 104

这题显然是字典树的题,不过看到数据量是2万,就偷个懒吧,谁让力扣给JS开的是10秒门槛呢,就当JS练手了。

var countPairs = function(nums, low, high) {
    var ans=0;
    for(var i=0;i=low && (nums[i]^nums[j])<=high)ans++;
        }
    }
    return ans;
};

1804. 实现 Trie (前缀树) II

前缀树

1805. 字符串中不同整数的数目

水题

1806. 还原排列的最少操作步数

1807. 替换字符串中的括号内容

水题

1812. 判断国际象棋棋盘中一个格子的颜色

给你一个坐标 coordinates ,它是一个字符串,表示国际象棋棋盘中一个格子的坐标。下图是国际象棋棋盘示意图。

力扣OJ(1601-2000)_第1张图片

如果所给格子的颜色是白色,请你返回 true,如果是黑色,请返回 false 。

给定坐标一定代表国际象棋棋盘上一个存在的格子。坐标第一个字符是字母,第二个字符是数字。

示例 1:

输入:coordinates = "a1"
输出:false
解释:如上图棋盘所示,"a1" 坐标的格子是黑色的,所以返回 false 。

示例 2:

输入:coordinates = "h3"
输出:true
解释:如上图棋盘所示,"h3" 坐标的格子是白色的,所以返回 true 。

示例 3:

输入:coordinates = "c7"
输出:false

提示:

  • coordinates.length == 2
  • 'a' <= coordinates[0] <= 'h'
  • '1' <= coordinates[1] <= '8'

class Solution {
public:
    bool squareIsWhite(string s) {
        return (s[0]+s[1])%2;
    }
};

1813. 句子相似性 III

水题

1814. 统计一个数组中好对子的数目

水题

1815. 得到新鲜甜甜圈的最多组数

模拟退火

1817. 查找用户活跃分钟数

给你用户在 LeetCode 的操作日志,和一个整数 k 。日志用一个二维整数数组 logs 表示,其中每个 logs[i] = [IDi, timei] 表示 ID 为 IDi 的用户在 timei 分钟时执行了某个操作。

多个用户 可以同时执行操作,单个用户可以在同一分钟内执行 多个操作 。

指定用户的 用户活跃分钟数(user active minutes,UAM) 定义为用户对 LeetCode 执行操作的 唯一分钟数 。 即使一分钟内执行多个操作,也只能按一分钟计数。

请你统计用户活跃分钟数的分布情况,统计结果是一个长度为 k 且 下标从 1 开始计数 的数组 answer ,对于每个 j(1 <= j <= k),answer[j] 表示 用户活跃分钟数 等于 j 的用户数。

返回上面描述的答案数组 answer 。

示例 1:

输入:logs = [[0,5],[1,2],[0,2],[0,5],[1,3]], k = 5
输出:[0,2,0,0,0]
解释:
ID=0 的用户执行操作的分钟分别是:5 、2 和 5 。因此,该用户的用户活跃分钟数为 2(分钟 5 只计数一次)
ID=1 的用户执行操作的分钟分别是:2 和 3 。因此,该用户的用户活跃分钟数为 2
2 个用户的用户活跃分钟数都是 2 ,answer[2] 为 2 ,其余 answer[j] 的值都是 0
示例 2:

输入:logs = [[1,1],[2,2],[2,3]], k = 4
输出:[1,1,0,0]
解释:
ID=1 的用户仅在分钟 1 执行单个操作。因此,该用户的用户活跃分钟数为 1
ID=2 的用户执行操作的分钟分别是:2 和 3 。因此,该用户的用户活跃分钟数为 2
1 个用户的用户活跃分钟数是 1 ,1 个用户的用户活跃分钟数是 2 
因此,answer[1] = 1 ,answer[2] = 1 ,其余的值都是 0
 

提示:

1 <= logs.length <= 104
0 <= IDi <= 109
1 <= timei <= 105
k 的取值范围是 [用户的最大用户活跃分钟数, 105]

class Solution {
public:
    vector findingUsersActiveMinutes(vector>& logs, int k) {
        map>m;
        for(auto &v:logs){
            m[v[0]].insert(v[1]);
        }
        vectorv(k,0);
        for(auto &p:m){
            v[p.second.size()-1]++;
        }
        return v;
    }
};

1819. 序列中不同最大公约数的数目

gcd

1822. 数组元素积的符号

已知函数 signFunc(x) 将会根据 x 的正负返回特定值:

  • 如果 x 是正数,返回 1 。
  • 如果 x 是负数,返回 -1 。
  • 如果 x 是等于 0 ,返回 0 。

给你一个整数数组 nums 。令 product 为数组 nums 中所有元素值的乘积。

返回 signFunc(product) 。

示例 1:

输入:nums = [-1,-2,-3,-4,3,2,1]
输出:1
解释:数组中所有值的乘积是 144 ,且 signFunc(144) = 1

示例 2:

输入:nums = [1,5,0,2,-3]
输出:0
解释:数组中所有值的乘积是 0 ,且 signFunc(0) = 0

示例 3:

输入:nums = [-1,1,-1,1,-1]
输出:-1
解释:数组中所有值的乘积是 -1 ,且 signFunc(-1) = -1

提示:

  • 1 <= nums.length <= 1000
  • -100 <= nums[i] <= 100
class Solution {
public:
    int arraySign(vector& nums) {
        int ans=0;
        for(auto n:nums){
            if(!n)return 0;
            if(n<0)ans++;
        }
        return 1-ans%2*2;
    }
};

1824. 最少侧跳次数(DP)

给你一个长度为 n 的 3 跑道道路 ,它总共包含 n + 1 个 点 ,编号为 0 到 n 。一只青蛙从 0 号点第二条跑道 出发 ,它想要跳到点 n 处。然而道路上可能有一些障碍。

给你一个长度为 n + 1 的数组 obstacles ,其中 obstacles[i] (取值范围从 0 到 3)表示在点 i 处的 obstacles[i] 跑道上有一个障碍。如果 obstacles[i] == 0 ,那么点 i 处没有障碍。任何一个点的三条跑道中 最多有一个 障碍。

比方说,如果 obstacles[2] == 1 ,那么说明在点 2 处跑道 1 有障碍。
这只青蛙从点 i 跳到点 i + 1 且跑道不变的前提是点 i + 1 的同一跑道上没有障碍。为了躲避障碍,这只青蛙也可以在 同一个 点处 侧跳 到 另外一条 跑道(这两条跑道可以不相邻),但前提是跳过去的跑道该点处没有障碍。

比方说,这只青蛙可以从点 3 处的跑道 3 跳到点 3 处的跑道 1 。
这只青蛙从点 0 处跑道 2 出发,并想到达点 n 处的 任一跑道 ,请你返回 最少侧跳次数 。

注意:点 0 处和点 n 处的任一跑道都不会有障碍。

示例 1:


输入:obstacles = [0,1,2,3,0]
输出:2 
解释:最优方案如上图箭头所示。总共有 2 次侧跳(红色箭头)。
注意,这只青蛙只有当侧跳时才可以跳过障碍(如上图点 2 处所示)。
示例 2:


输入:obstacles = [0,1,1,3,3,0]
输出:0
解释:跑道 2 没有任何障碍,所以不需要任何侧跳。
示例 3:


输入:obstacles = [0,2,1,0,3,0]
输出:2
解释:最优方案如上图所示。总共有 2 次侧跳。
 

提示:

obstacles.length == n + 1
1 <= n <= 5 * 105
0 <= obstacles[i] <= 3
obstacles[0] == obstacles[n] == 0


class Solution {
public:
    int minSideJumps(const vector& ob) {
        vectorans(3, 0);
        for (int i = ob.size() - 2; i >= 0; i--) {
            int flag = 0;
            int k=INT_MAX;
            for (int j = 1; j <= 3; j++) {
                if (ob[i] == j) {
                    ans[j - 1] = -1;
                }
                else if (ob[i + 1] == j)flag = j;
                else k = min(k,ans[j - 1]);
            }
            if (flag)ans[flag - 1] = k+1;
        }
        return ans[1];
    }
};

1825. 求出 MK 平均值

给你两个整数 m 和 k ,以及数据流形式的若干整数。你需要实现一个数据结构,计算这个数据流的 MK 平均值 。

MK 平均值 按照如下步骤计算:

如果数据流中的整数少于 m 个,MK 平均值 为 -1 ,否则将数据流中最后 m 个元素拷贝到一个独立的容器中。
从这个容器中删除最小的 k 个数和最大的 k 个数。
计算剩余元素的平均值,并 向下取整到最近的整数 。
请你实现 MKAverage 类:

MKAverage(int m, int k) 用一个空的数据流和两个整数 m 和 k 初始化 MKAverage 对象。
void addElement(int num) 往数据流中插入一个新的元素 num 。
int calculateMKAverage() 对当前的数据流计算并返回 MK 平均数 ,结果需 向下取整到最近的整数 。
 

示例 1:

输入:
["MKAverage", "addElement", "addElement", "calculateMKAverage", "addElement", "calculateMKAverage", "addElement", "addElement", "addElement", "calculateMKAverage"]
[[3, 1], [3], [1], [], [10], [], [5], [5], [5], []]
输出:
[null, null, null, -1, null, 3, null, null, null, 5]

解释:
MKAverage obj = new MKAverage(3, 1); 
obj.addElement(3);        // 当前元素为 [3]
obj.addElement(1);        // 当前元素为 [3,1]
obj.calculateMKAverage(); // 返回 -1 ,因为 m = 3 ,但数据流中只有 2 个元素
obj.addElement(10);       // 当前元素为 [3,1,10]
obj.calculateMKAverage(); // 最后 3 个元素为 [3,1,10]
                          // 删除最小以及最大的 1 个元素后,容器为 [3]
                          // [3] 的平均值等于 3/1 = 3 ,故返回 3
obj.addElement(5);        // 当前元素为 [3,1,10,5]
obj.addElement(5);        // 当前元素为 [3,1,10,5,5]
obj.addElement(5);        // 当前元素为 [3,1,10,5,5,5]
obj.calculateMKAverage(); // 最后 3 个元素为 [5,5,5]
                          // 删除最小以及最大的 1 个元素后,容器为 [5]
                          // [5] 的平均值等于 5/1 = 5 ,故返回 5
 

提示:

3 <= m <= 105
1 <= k*2 < m
1 <= num <= 105
addElement 与 calculateMKAverage 总操作次数不超过 105 次。

template
vector queToVec(queueq)
{
	vectorv;
	while (!q.empty())v.push_back(q.front()), q.pop();
	return v;
}
template
void delOnlyOne(T &x, T2 n)
{
	auto it = x.find(n);
	if (it != x.end())x.erase(it);
}

class MKAverage {
public:
	MKAverage(int m, int k) {
		this->m = m;
		this->k = k;
		while (!q.empty())q.pop();
		sum2 = 0;
	}

	void addElement(int num) {
		if (q.size() < m - 1) {
			q.push(num);
			return;
		}
		if (q.size() == m - 1) {
			q.push(num);
			auto v = queToVec(q);
			sort(v.begin(), v.end());
			for (int i = 0; i < k; i++)s1.insert(v[i]);
			for (int i = k; i < m - k; i++)s2.insert(v[i]), sum2 += v[i];
			for (int i = m-k; i < m; i++)s3.insert(v[i]);
			return;
		}
		del(q.front());
		q.pop();
		q.push(num);
		push(num);
	}

	int calculateMKAverage() {
		if (q.size() < m)return -1;
		return sum2 / (m - k * 2);
	}
private:
	void del(int x)
	{
		int flag;
		if (x < *s2.begin())delOnlyOne(s1, x), flag = 1;
		else if (x < *s3.begin())delOnlyOne(s2, x), flag = 2, sum2 -= x;
		else delOnlyOne(s3, x), flag = 3;
		if (flag < 3)s2.insert(*s3.begin()), sum2+= *s3.begin(),s3.erase(s3.begin());
		if (flag < 2)s1.insert(*s2.begin()), sum2-= *s2.begin(),s2.erase(s2.begin());
	}
	void push(int x)
	{
		s1.insert(x);
		s2.insert(*s1.rbegin()), sum2 += *s1.rbegin(), s1.erase(--s1.end());
		s3.insert(*s2.rbegin()), sum2-= *s2.rbegin(),s2.erase(--s2.end());
	}
	queueq;
	multisets1, s2, s3;
	int m, k,sum2;
};

1827. 最少操作使数组递增

给你一个整数数组 nums (下标从 0 开始)。每一次操作中,你可以选择数组中一个元素,并将它增加 1 。

  • 比方说,如果 nums = [1,2,3] ,你可以选择增加 nums[1] 得到 nums = [1,3,3] 。

请你返回使 nums 严格递增 的 最少 操作次数。

我们称数组 nums 是 严格递增的 ,当它满足对于所有的 0 <= i < nums.length - 1 都有 nums[i] < nums[i+1] 。一个长度为 1 的数组是严格递增的一种特殊情况。

示例 1:

输入:nums = [1,1,1]
输出:3
解释:你可以进行如下操作:
1) 增加 nums[2] ,数组变为 [1,1,2] 。
2) 增加 nums[1] ,数组变为 [1,2,2] 。
3) 增加 nums[2] ,数组变为 [1,2,3] 。

示例 2:

输入:nums = [1,5,2,4,1]
输出:14

示例 3:

输入:nums = [8]
输出:0

提示:

  • 1 <= nums.length <= 5000
  • 1 <= nums[i] <= 104
class Solution {
public:
	int minOperations(vector& nums) {
		int ans = 0;
		for (int i = 1; i < nums.size(); i++)
			if (nums[i] <= nums[i - 1])ans += nums[i - 1] - nums[i]+1, nums[i] = nums[i - 1] + 1;
		return ans;
	}
};

1828. 统计一个圆中点的数目

水题

1835. 所有数对按位与结果的异或和

贡献法

1862. 向下取整数对和

数论

1863. 找出所有子集的异或总和再求和

贡献法

1884. 鸡蛋掉落-两枚鸡蛋

单人决策

1902. 给定二叉搜索树的插入顺序求深度

红黑树

1908. Nim 游戏 II

博弈

1911. 最大子序列交替和

数列DP

1922. 统计好数字的数目

快速幂

1971. 寻找图中是否存在路径

BFS

1973. 值等于子节点值之和的节点数量

二叉树

1979. 找出数组的最大公约数

欧几里得

1989. 捉迷藏中可捕获的最大人数

双指针、多指针

1992. 找到所有的农场组

并查集

1998. 数组的最大公因数排序

因式分解

1999. 最小的仅由两个数组成的倍数

给你三个整数, kdigit1和 digit2, 你想要找到满足以下条件的 最小 整数:

  • 大于k 且是 k 的倍数
  • 仅由digit1 和 digit2 组成,即 每一位数 均是 digit1 或 digit2

请你返回 最小的满足这两个条件的整数,如果不存在这样的整数,或者最小的满足这两个条件的整数不在32位整数范围(0~231-1),就返回 -1 。

示例 1:

输入:k = 2, digit1 = 0, digit2 = 2
输出:20
解释:
20 是第一个仅有数字0和2组成的,比2大且是2的倍数的整数。

示例 2:

输入:k = 3, digit1 = 4, digit2 = 2
输出:24
解释:
24 是第一个仅有数字 2 和 4 组成的,比 3 大且是 3 的倍数的整数。

示例 3:

输入:k = 2, digit1 = 0, digit2 = 0
输出:-1
解释:
不存在仅由 0 组成的比 2 大且是 2 的倍数的整数,因此返回 -1 。

提示:

  • 1 <= k <= 1000
  • 0 <= digit1 <= 9
  • 0 <= digit2 <= 9
class Solution {
public:
	int findInteger(int k, int digit1, int digit2) {
		if (digit1 > digit2)digit1 ^= digit2 ^= digit1 ^= digit2;
		vectorv{ 0 };
		while (!v.empty())
		{
			vectorv2;
			for (auto vi : v) {
				long long x = vi * 10 + digit1;				
				if (x <= INT_MAX) {
					if (x > k && x % k == 0)return x;
					if(x)v2.push_back(x);
				}
				x = vi * 10 + digit2;
				if (x <= INT_MAX) {
					if (x > k && x % k == 0)return x;
					if (x)v2.push_back(x);
				}
			}
			v = v2;
		}
		return -1;
	}
};

你可能感兴趣的:(leetcode,算法,1024程序员节)