力扣OJ(0401-600)

目录

404. 左叶子之和

408. 有效单词缩写

410. 分割数组的最大值

412. Fizz Buzz

414. 第三大的数

416. 分割等和子集

417. 太平洋大西洋水流问题

419. 甲板上的战舰

421. 数组中两个数的最大异或值

422. 有效的单词方块

426. 将二叉搜索树转化为排序的双向链表

429. N叉树的层序遍历

430. 扁平化多级双向链表

431. 将 N 叉树编码为二叉树

437. 路径总和 III

438. 找到字符串中所有字母异位词

441. 排列硬币

444. 序列重建

445. 两数相加 II

447. 回旋镖的数量

451. 根据字符出现频率排序

454. 四数相加 II

458. 可怜的小猪

459. 重复的子字符串

461. 汉明距离

464. 我能赢吗

469. 凸多边形

470. 用 Rand7() 实现 Rand10()

474. 一和零

476. 数字的补数

477. 汉明距离总和

478. 在圆内随机生成点

479. 最大回文数乘积

483. 最小好进制

484. 寻找排列

485. 最大连续 1 的个数

486. 预测赢家

487. 最大连续1的个数 II

490. 迷宫

492. 构造矩形

494. 目标和

496. 下一个更大元素 I

497. 非重叠矩形中的随机点

499. 迷宫 III

503. 下一个更大元素 II

504. 七进制数

505. 迷宫 II

507. 完美数

509. 斐波那契数

510. 二叉搜索树中的中序后继 II

511. 游戏玩法分析 I

513. 找树左下角的值

515. 在每个树行中找最大值

518. 零钱兑换 II

519. 随机翻转矩阵

520. 检测大写字母

521. 最长特殊序列 Ⅰ

523. 连续的子数组和

525. 连续数组

528. 按权重随机选择

529. 扫雷游戏

531. 孤独像素 I

532. 数组中的 k-diff 数对

533. 孤独像素 II

535. TinyURL 的加密与解密

538. 把二叉搜索树转换为累加树

539. 最小时间差

540. 有序数组中的单一元素

542. 01 矩阵

545. 二叉树的边界

547. 省份数量

549. 二叉树最长连续序列 II

552. 学生出勤记录 II

553. 最优除法

555. 分割连接字符串

556. 下一个更大元素 III 

559. N 叉树的最大深度

560. 和为K的子数组

562. 矩阵中最长的连续1线段

565. 数组嵌套

567. 字符串的排列

575. 分糖果

581. 最短无序连续子数组

589. N 叉树的前序遍历

590. N 叉树的后序遍历


404. 左叶子之和

二叉树

408. 有效单词缩写

水题

410. 分割数组的最大值

二分法

412. Fizz Buzz

水题

414. 第三大的数

rust

416. 分割等和子集

背包问题

417. 太平洋大西洋水流问题

rust实战

419. 甲板上的战舰

并查集

421. 数组中两个数的最大异或值

 基数树(radix tree)

422. 有效的单词方块

给你一个单词序列,判断其是否形成了一个有效的单词方块。

有效的单词方块是指此由单词序列组成的文字方块的 第 k 行 和 第 k 列 (0 ≤ k < max(行数, 列数)) 所显示的字符串完全相同。

注意:

  1. 给定的单词数大于等于 1 且不超过 500。
  2. 单词长度大于等于 1 且不超过 500。
  3. 每个单词只包含小写英文字母 a-z

示例 1:

输入:
[
  "abcd",
  "bnrt",
  "crmy",
  "dtye"
]

输出:
true

解释:
第 1 行和第 1 列都是 "abcd"。
第 2 行和第 2 列都是 "bnrt"。
第 3 行和第 3 列都是 "crmy"。
第 4 行和第 4 列都是 "dtye"。

因此,这是一个有效的单词方块。

示例 2:

输入:
[
  "abcd",
  "bnrt",
  "crm",
  "dt"
]

输出:
true

解释:
第 1 行和第 1 列都是 "abcd"。
第 2 行和第 2 列都是 "bnrt"。
第 3 行和第 3 列都是 "crm"。
第 4 行和第 4 列都是 "dt"。

因此,这是一个有效的单词方块。

示例 3:

输入:
[
  "ball",
  "area",
  "read",
  "lady"
]

输出:
false

解释:
第 3 行是 "read" ,然而第 3 列是 "lead"。

因此,这 不是 一个有效的单词方块。
class Solution {
public:
    bool validWordSquare(vector<string>& words) {
        for(int i=0;i<words.size();i++)for(int j=0;j<words[i].size();j++){
            if(j>=words.size() || i>=words[j].size())return false;
            if(words[i][j]!=words[j][i])return false;
        }
        return true;
    }
};

426. 将二叉搜索树转化为排序的双向链表

双向循环链表

429. N叉树的层序遍历

多叉树

430. 扁平化多级双向链表

双向链表

431. 将 N 叉树编码为二叉树

树 树、森林_nameofcsdn的博客-CSDN博客

437. 路径总和 III

DFS

438. 找到字符串中所有字母异位词

剑指 Offer II 015. 字符串中的所有变位词

https://blog.csdn.net/nameofcsdn/article/details/119833252

441. 排列硬币

你总共有 n 枚硬币,并计划将它们按阶梯状排列。对于一个由 k 行组成的阶梯,其第 i 行必须正好有 i 枚硬币。阶梯的最后一行 可能 是不完整的。

给你一个数字 n ,计算并返回可形成 完整阶梯行 的总行数。

示例 1:

输入:n = 5
输出:2
解释:因为第三行不完整,所以返回 2 。

示例 2:

输入:n = 8
输出:3
解释:因为第四行不完整,所以返回 3 。

提示:

  • 1 <= n <= 231 - 1
class Solution {
public:
	int arrangeCoins(long long n) {
		return sqrt(n * 2 + 0.25) - 0.5;
	}
};

444. 序列重建

LCR 115. 序列重建

445. 两数相加 II

剑指 Offer II 025. 链表中的两数相加

447. 回旋镖的数量

给定平面上 n 对 互不相同 的点 points ,其中 points[i] = [xi, yi] 。回旋镖 是由点 (i, j, k) 表示的元组 ,其中 i 和 j 之间的距离和 i 和 k 之间的欧式距离相等(需要考虑元组的顺序)。

返回平面上所有回旋镖的数量。

示例 1:

输入:points = [[0,0],[1,0],[2,0]]
输出:2
解释:两个回旋镖为 [[1,0],[0,0],[2,0]][[1,0],[2,0],[0,0]]

示例 2:

输入:points = [[1,1],[2,2],[3,3]]
输出:2

示例 3:

输入:points = [[1,1]]
输出:0

提示:

  • n == points.length
  • 1 <= n <= 500
  • points[i].length == 2
  • -104 <= xi, yi <= 104
  • 所有点都 互不相同
class Solution {
public:
    int numberOfBoomerangs(vector<vector<int>>& points) {
        vector<map<int,int>>vm(points.size());
        for(int i=0;i<points.size();i++){
            for(int j=i+1;j<points.size();j++){
                int len1 = points[i][0]-points[j][0];
                int len2 = points[i][1]-points[j][1];
                int len = len1*len1+len2*len2;
                vm[i][len]++,vm[j][len]++;
            }
        }
        int ans=0;
        for(auto &m:vm){
            for(auto mi:m){
                ans+=mi.second*(mi.second-1);
            }
        }
        return ans;
    }
};

451. 根据字符出现频率排序

题目:

给定一个字符串,请将字符串里的字符按照出现的频率降序排列。

示例 1:

输入:
"tree"

输出:
"eert"

解释:
'e'出现两次,'r'和't'都只出现一次。
因此'e'必须出现在'r'和't'之前。此外,"eetr"也是一个有效的答案。
示例 2:

输入:
"cccaaa"

输出:
"cccaaa"

解释:
'c'和'a'都出现三次。此外,"aaaccc"也是有效的答案。
注意"cacaca"是不正确的,因为相同的字母必须放在一起。
示例 3:

输入:
"Aabb"

输出:
"bbAa"

解释:
此外,"bbaA"也是一个有效的答案,但"Aabb"是不正确的。
注意'A'和'a'被认为是两种不同的字符。

代码:

struct dist
{
	char c;
	int fre;
};
struct cmp
{
	bool operator()(dist a, dist b)
	{
		return a.fre < b.fre;
	}
};
 
class Solution {
public:
	string frequencySort(string s) {
		map<char, int> m;
		priority_queue<dist, vector<dist>, cmp>que;
		dist d;
		for (int i = 0; i < s.length();i++)
		{
			m[s[i]]++;
		}
		for (auto it = m.begin(); it != m.end(); it++)
		{
			d.c = (*it).first, d.fre = (*it).second, que.push(d);
		}
		string ans = "";
		while (!que.empty())
		{
			d = que.top();
			que.pop();
			while(d.fre--)ans += d.c;
		}
		return ans;
	}
};

454. 四数相加 II

数组和集合的搜索 数组和集合的搜索_nameofcsdn的博客-CSDN博客

458. 可怜的小猪

单人决策问题

459. 重复的子字符串

KMP

461. 汉明距离

题目:

两个整数之间的汉明距离指的是这两个数字对应二进制位不同的位置的数目。

给出两个整数 x 和 y,计算它们之间的汉明距离。

注意:
0 ≤ x, y < 231.

示例:

输入: x = 1, y = 4

输出: 2

解释:
1   (0 0 0 1)
4   (0 1 0 0)
       ↑   ↑

上面的箭头指出了对应二进制位不同的位置。

代码:

class Solution {
public:
	int hammingWeight(uint32_t n) {
		int ans = 0;
		while (n)
		{
			n ^= (n&(-n));
			ans++;
		}
		return ans;
	}
	int hammingDistance(int x, int y) {
		return hammingWeight(x^y);
	}
};

464. 我能赢吗

公平游戏

469. 凸多边形

计算几何

470. 用 Rand7() 实现 Rand10()

拒绝采样(Rejection Sampling)

474. 一和零

背包

476. 数字的补数

位运算

477. 汉明距离总和

贡献法

478. 在圆内随机生成点

拒绝采样(Rejection Sampling)

479. 最大回文数乘积

其他数论问题

483. 最小好进制

不定方程

484. 寻找排列

贪心

485. 最大连续 1 的个数

给定一个二进制数组 nums , 计算其中最大连续 1 的个数。

示例 1:

输入:nums = [1,1,0,1,1,1]
输出:3
解释:开头的两位和最后的三位都是连续 1 ,所以最大连续 1 的个数是 3.
示例 2:

输入:nums = [1,0,1,1,0,1]
输出:2
 

提示:

1 <= nums.length <= 105
nums[i] 不是 0 就是 1.

class Solution {
public:
	int findMaxConsecutiveOnes(vector<int>& nums) {
		int n = 0, ans = 0;
		for (int i = 0; i < nums.size(); i++) {
			if (nums[i])n++;
			else ans = max(ans, n), n = 0;
		}
		return max(ans, n);
	}
};

486. 预测赢家

博弈DP

487. 最大连续1的个数 II

给定一个二进制数组 nums ,如果最多可以翻转一个 0 ,则返回数组中连续 1 的最大个数。

示例 1:

输入:nums = [1,0,1,1,0]
输出:4
解释:翻转第一个 0 可以得到最长的连续 1。
     当翻转以后,最大连续 1 的个数为 4。
示例 2:

输入:nums = [1,0,1,1,0,1]
输出:4
 

提示:

1 <= nums.length <= 105
nums[i] 不是 0 就是 1.
 

进阶:如果输入的数字是作为 无限流 逐个输入如何处理?换句话说,内存不能存储下所有从流中输入的数字。您可以有效地解决吗?

class Solution {
public:
	int findMaxConsecutiveOnes(vector<int>& nums) {
		int a = -1, b = -1, c = -1, d = -1, ans = 0;
		for (int i = 0; i <= nums.size(); i++) {
			if (i == nums.size() || nums[i] == 0) {
				d = i;
				ans = max(ans, d - b - 1);
				a = b, b = c, c = d;
			}
		}
		return ans;
	}
};

490. 迷宫

puzzle(017.1)Orac

492. 构造矩形

作为一位web开发者, 懂得怎样去规划一个页面的尺寸是很重要的。 所以,现给定一个具体的矩形页面面积,你的任务是设计一个长度为 L 和宽度为 W 且满足以下要求的矩形的页面。要求:

  1. 你设计的矩形页面必须等于给定的目标面积。
  2. 宽度 W 不应大于长度 L ,换言之,要求 L >= W
  3. 长度 L 和宽度 W 之间的差距应当尽可能小。

返回一个 数组 [L, W],其中 L 和 W 是你按照顺序设计的网页的长度和宽度
 

示例1:

输入: 4
输出: [2, 2]
解释: 目标面积是 4, 所有可能的构造方案有 [1,4], [2,2], [4,1]。
但是根据要求2,[1,4] 不符合要求; 根据要求3,[2,2] 比 [4,1] 更能符合要求. 所以输出长度 L 为 2, 宽度 W 为 2。

示例 2:

输入: area = 37
输出: [37,1]

示例 3:

输入: area = 122122
输出: [427,286]

提示:

  • 1 <= area <= 107
class Solution {
public:
    vector<int> constructRectangle(int area) {
        int a=1,ans=1;
        while(a+1<area/a){
            a++;
            if(area/a*a==area)ans=a;
        }
        return vector<int>{area/ans,ans};
    }
};

494. 目标和

01背包

496. 下一个更大元素 I

给定两个 没有重复元素 的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集。找到 nums1 中每个元素在 nums2 中的下一个比其大的值。

nums1 中数字 x 的下一个更大元素是指 x 在 nums2 中对应位置的右边的第一个比 x 大的元素。如果不存在,对应位置输出 -1 。

示例 1:

输入: nums1 = [4,1,2], nums2 = [1,3,4,2].
输出: [-1,3,-1]
解释:
    对于num1中的数字4,你无法在第二个数组中找到下一个更大的数字,因此输出 -1。
    对于num1中的数字1,第二个数组中数字1右边的下一个较大数字是 3。
    对于num1中的数字2,第二个数组中没有下一个更大的数字,因此输出 -1。
示例 2:

输入: nums1 = [2,4], nums2 = [1,2,3,4].
输出: [3,-1]
解释:
    对于 num1 中的数字 2 ,第二个数组中的下一个较大数字是 3 。
    对于 num1 中的数字 4 ,第二个数组中没有下一个更大的数字,因此输出 -1 。
 

提示:

nums1和nums2中所有元素是唯一的。
nums1和nums2 的数组大小都不超过1000。

这个题目很简单,我主要用来锻造我的模板:

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        vector<int>ans=GetNumFromId(nums2,Fmaxrig(nums2));
        map<int,int>m=VectorToMap(nums2,ans);
        ans=VmToVector(nums1,m);
        return ans;
    }
};

497. 非重叠矩形中的随机点

给定一个由非重叠的轴对齐矩形的数组 rects ,其中 rects[i] = [ai, bi, xi, yi] 表示 (ai, bi) 是第 i 个矩形的左下角点,(xi, yi) 是第 i 个矩形的右上角点。设计一个算法来随机挑选一个被某一矩形覆盖的整数点。矩形周长上的点也算做是被矩形覆盖。所有满足要求的点必须等概率被返回。

在给定的矩形覆盖的空间内的任何整数点都有可能被返回。

请注意 ,整数点是具有整数坐标的点。

实现 Solution 类:

  • Solution(int[][] rects) 用给定的矩形数组 rects 初始化对象。
  • int[] pick() 返回一个随机的整数点 [u, v] 在给定的矩形所覆盖的空间内。

示例 1:

输入: 
["Solution", "pick", "pick", "pick", "pick", "pick"]
[[[[-2, -2, 1, 1], [2, 2, 4, 6]]], [], [], [], [], []]
输出: 
[null, [1, -2], [1, -1], [-1, -2], [-2, -2], [0, 0]]

解释:
Solution solution = new Solution([[-2, -2, 1, 1], [2, 2, 4, 6]]);
solution.pick(); // 返回 [1, -2]
solution.pick(); // 返回 [1, -1]
solution.pick(); // 返回 [-1, -2]
solution.pick(); // 返回 [-2, -2]
solution.pick(); // 返回 [0, 0]

提示:

  • 1 <= rects.length <= 100
  • rects[i].length == 4
  • -109 <= ai < xi <= 109
  • -109 <= bi < yi <= 109
  • xi - ai <= 2000
  • yi - bi <= 2000
  • 所有的矩形不重叠。
  • pick 最多被调用 104 次。
class Solution {
public:
    Solution(vector<vector<int>>& rects) {
        v=rects;
        long long s=0,s2=0;
        for(auto vi:v){
            s+=(long long)(vi[2]+1-vi[0])*(vi[3]+1-vi[1]);
        }
        for(auto vi:v){
            s2+=(long long)(vi[2]+1-vi[0])*(vi[3]+1-vi[1]);
            p.push_back(s2*1.0/s);
        }
    }
    int randIn(int x,int y){
        return rand()%(y+1-x)+x;
    }
    vector<int> pick() {
        double x = rand()%10000/10000.0;
        for(int i=0;i<p.size();i++){
            if(p[i]>=x){
                return vector<int>{randIn(v[i][0],v[i][2]),randIn(v[i][1],v[i][3])};
            }
        }
        return vector<int>{0,0};
    }
    vector<vector<int>> v;
    vector<double>p;
};

499. 迷宫 III

单源最短路径

503. 下一个更大元素 II

给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1。

示例 1:

输入: [1,2,1]
输出: [2,-1,2]
解释: 第一个 1 的下一个更大的数是 2;
数字 2 找不到下一个更大的数; 
第二个 1 的下一个最大的数需要循环搜索,结果也是 2。

class Solution {
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
        vector<int>t=nums;
        t.resize(nums.size()*2);
        copy(nums.begin(),nums.end(),t.begin()+nums.size());
        vector<int>tmp=GetNumFromId(t,Fmaxrig(t));
        vector<int>ans=nums;
        copy(tmp.begin(),tmp.begin()+tmp.size()/2,ans.begin());
        return ans;
    }
};

504. 七进制数

给定一个整数 num,将其转化为 7 进制,并以字符串形式输出。

示例 1:

输入: num = 100
输出: "202"

示例 2:

输入: num = -7
输出: "-10"

提示:

  • -107 <= num <= 107
class Solution {
public:
    string convertToBase7(int num) {
        if(num<0)return "-"+convertToBase7(-num);
        string ans;
        while(num>=7)ans=to_string(num%7)+ans,num/=7;
        return to_string(num%7)+ans;
    }
};

505. 迷宫 II

单源最短路径

507. 完美数

数论数

509. 斐波那契数

斐波那契数列

510. 二叉搜索树中的中序后继 II

二叉搜索树 二叉搜索树(BST)_nameofcsdn的博客-CSDN博客

511. 游戏玩法分析 I

活动表 Activity

+--------------+---------+
| Column Name  | Type    |
+--------------+---------+
| player_id    | int     |
| device_id    | int     |
| event_date   | date    |
| games_played | int     |
+--------------+---------+
在 SQL 中,表的主键是 (player_id, event_date)。
这张表展示了一些游戏玩家在游戏平台上的行为活动。
每行数据记录了一名玩家在退出平台之前,当天使用同一台设备登录平台后打开的游戏的数目(可能是 0 个)。

查询每位玩家 第一次登陆平台的日期

查询结果的格式如下所示:

Activity 表:
+-----------+-----------+------------+--------------+
| player_id | device_id | event_date | games_played |
+-----------+-----------+------------+--------------+
| 1         | 2         | 2016-03-01 | 5            |
| 1         | 2         | 2016-05-02 | 6            |
| 2         | 3         | 2017-06-25 | 1            |
| 3         | 1         | 2016-03-02 | 0            |
| 3         | 4         | 2018-07-03 | 5            |
+-----------+-----------+------------+--------------+

Result 表:
+-----------+-------------+
| player_id | first_login |
+-----------+-------------+
| 1         | 2016-03-01  |
| 2         | 2017-06-25  |
| 3         | 2016-03-02  |
+-----------+-------------+
SELECT player_id, MIN(event_date) as first_login  FROM activity GROUP BY player_id;

513. 找树左下角的值

二叉树BFS

515. 在每个树行中找最大值

剑指 Offer II 044. 二叉树每层的最大值 https://blog.csdn.net/nameofcsdn/article/details/119833252

518. 零钱兑换 II

完全背包

519. 随机翻转矩阵

给你一个 m x n 的二元矩阵 matrix ,且所有值被初始化为 0 。请你设计一个算法,随机选取一个满足 matrix[i][j] == 0 的下标 (i, j) ,并将它的值变为 1 。所有满足 matrix[i][j] == 0 的下标 (i, j) 被选取的概率应当均等。

尽量最少调用内置的随机函数,并且优化时间和空间复杂度。

实现 Solution 类:

  • Solution(int m, int n) 使用二元矩阵的大小 m 和 n 初始化该对象
  • int[] flip() 返回一个满足 matrix[i][j] == 0 的随机下标 [i, j] ,并将其对应格子中的值变为 1
  • void reset() 将矩阵中所有的值重置为 0

示例:

输入
["Solution", "flip", "flip", "flip", "reset", "flip"]
[[3, 1], [], [], [], [], []]
输出
[null, [1, 0], [2, 0], [0, 0], null, [2, 0]]

解释
Solution solution = new Solution(3, 1);
solution.flip();  // 返回 [1, 0],此时返回 [0,0]、[1,0] 和 [2,0] 的概率应当相同
solution.flip();  // 返回 [2, 0],因为 [1,0] 已经返回过了,此时返回 [2,0] 和 [0,0] 的概率应当相同
solution.flip();  // 返回 [0, 0],根据前面已经返回过的下标,此时只能返回 [0,0]
solution.reset(); // 所有值都重置为 0 ,并可以再次选择下标返回
solution.flip();  // 返回 [2, 0],此时返回 [0,0]、[1,0] 和 [2,0] 的概率应当相同

提示:

  • 1 <= m, n <= 104
  • 每次调用flip 时,矩阵中至少存在一个值为 0 的格子。
  • 最多调用 1000 次 flip 和 reset 方法。
class Solution {
public:
    Solution(int m, int n) {
        this->m=m,this->n=n;
        reset();
    }
    
    vector<int> flip() {
        return v[id++];
    }
    
    void reset() {
        v.clear();
        id=0;
        static int a=0;
        srand(a++);
        int x=rand(),y=rand();
        int num=0;
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                v.push_back(vector<int>{(i+x)%m,(j+y)%n});
                if(num++>1000)break;
            }
        }
    }
    int m,n,id;
    vector<vector<int>>v;
};

520. 检测大写字母

我们定义,在以下情况时,单词的大写用法是正确的:

  • 全部字母都是大写,比如 "USA" 。
  • 单词中所有字母都不是大写,比如 "leetcode" 。
  • 如果单词不只含有一个字母,只有首字母大写, 比如 "Google" 。

给你一个字符串 word 。如果大写用法正确,返回 true ;否则,返回 false 。

示例 1:

输入:word = "USA"
输出:true

示例 2:

输入:word = "FlaG"
输出:false

提示:

  • 1 <= word.length <= 100
  • word 由小写和大写英文字母组成
class Solution {
public:
    bool detectCapitalUse(string word) {
        int n=0;
        for(int i=0;i<word.length();i++){
            if(word[i]>='a')n++;
        }
        return n==word.length()||n==0||(n==word.length()-1&&word[0]<'a');
    }
};

521. 最长特殊序列 Ⅰ

给你两个字符串 a 和 b,请返回 这两个字符串中 最长的特殊序列  的长度。如果不存在,则返回 -1 。

「最长特殊序列」 定义如下:该序列为 某字符串独有的最长

子序列

(即不能是其他字符串的子序列) 。

字符串 s 的子序列是在从 s 中删除任意数量的字符后可以获得的字符串。

  • 例如,"abc" 是 "aebdc" 的子序列,因为删除 "aebdc" 中斜体加粗的字符可以得到 "abc" 。 "aebdc" 的子序列还包括 "aebdc" 、 "aeb" 和 "" (空字符串)。

示例 1:

输入: a = "aba", b = "cdc"
输出: 3
解释: 最长特殊序列可为 "aba" (或 "cdc"),两者均为自身的子序列且不是对方的子序列。

示例 2:

输入:a = "aaa", b = "bbb"
输出:3
解释: 最长特殊序列是 "aaa" 和 "bbb" 。

示例 3:

输入:a = "aaa", b = "aaa"
输出:-1
解释: 字符串 a 的每个子序列也是字符串 b 的每个子序列。同样,字符串 b 的每个子序列也是字符串 a 的子序列。

提示:

  • 1 <= a.length, b.length <= 100
  • a 和 b 由小写英文字母组成
class Solution {
public:
    int findLUSlength(string a, string b) {
        return a==b?-1:max(a.length(),b.length());
    }
};

523. 连续的子数组和

给定一个包含非负数的数组和一个目标整数 k,编写一个函数来判断该数组是否含有连续的子数组,其大小至少为 2,总和为 k 的倍数,即总和为 n*k,其中 n 也是一个整数。

示例 1:

输入: [23,2,4,6,7], k = 6
输出: True
解释: [2,4] 是一个大小为 2 的子数组,并且和为 6。
示例 2:

输入: [23,2,6,4,7], k = 6
输出: True
解释: [23,2,6,4,7]是大小为 5 的子数组,并且和为 42。
说明:

数组的长度不会超过10,000。
你可以认为所有数字总和在 32 位有符号整数范围内。

class Solution {
public:
    bool checkSubarraySum(vector<int>& nums, int k) {
        if(k==0)
        {
            for(int i=1;i<nums.size();i++)
            {
                if(nums[i]==0&&nums[i-1]==0)return true;
            }
            return false;
        }
        map<int,int>m;
        int s=0;
        if(k<0)k=-k;    
        for(int i=0;i<nums.size();i++)
        {
            s+=nums[i];
            s%=k;
            if(m[s]>0||s==0)
            {
                if(m[s]<i)return true;
            }
            else m[s]=i+1;
        }
        return false;
    }
};

525. 连续数组

剑指 Offer II 010. 和为 k 的子数组 https://blog.csdn.net/nameofcsdn/article/details/119833252

528. 按权重随机选择

剑指 Offer II 071. 按权重生成随机数 https://blog.csdn.net/nameofcsdn/article/details/119833252

529. 扫雷游戏

BFS

531. 孤独像素 I

给你一个大小为 m x n 的图像 picture ,图像由黑白像素组成,'B' 表示黑色像素,'W' 表示白色像素,请你统计并返回图像中 黑色 孤独像素的数量。

黑色孤独像素 的定义为:如果黑色像素 'B' 所在的同一行和同一列不存在其他黑色像素,那么这个黑色像素就是黑色孤独像素。

示例 1:

输入:picture = [["W","W","B"],["W","B","W"],["B","W","W"]]
输出:3
解释:全部三个 'B' 都是黑色的孤独像素

示例 2:

输入:picture = [["B","B","B"],["B","B","W"],["B","B","B"]]
输出:0

提示:

  • m == picture.length
  • n == picture[i].length
  • 1 <= m, n <= 500
  • picture[i][j] 为 'W' 或 'B'
class Solution {
public:
    int findLonelyPixel(vector<vector<char>>& v) {
        vector<int>r(v.size(), 0);
        vector<int>c(v[0].size(), 0);
        for (int i = 0; i < v.size(); i++) {
            for (int j = 0; j < v[0].size(); j++) {
                if (v[i][j] == 'B')r[i]++, c[j]++;
            }
        }
        int ans = 0;
        for (int i = 0; i < v.size(); i++) {
            for (int j = 0; j < v[0].size(); j++) {
                if (v[i][j] == 'B' && r[i]==1&&c[j]==1)ans++;
            }
        }
        return ans;
    }
};

532. 数组中的 k-diff 数对

rust

533. 孤独像素 II

给你一个大小为 m x n 的二维字符数组 picture ,表示一张黑白图像,数组中的 'B' 表示黑色像素,'W' 表示白色像素。另给你一个整数 target ,请你找出并返回符合规则的 黑色 孤独像素的数量。

黑色孤独像素是指位于某一特定位置 (r, c) 的字符 'B' ,其中:

  • 行 r 和列 c 中的黑色像素恰好有 target 个。
  • 列 c 中所有黑色像素所在的行必须和行 r 完全相同。

示例 1:

输入:picture = [["W","B","W","B","B","W"],["W","B","W","B","B","W"],["W","B","W","B","B","W"],["W","W","B","W","B","W"]], target = 3
输出:6
解释:所有绿色的 'B' 都是我们所求的像素(第 1 列和第 3 列的所有 'B' )
以行 r = 0 和列 c = 1 的 'B' 为例:
- 规则 1 ,行 r = 0 和列 c = 1 都恰好有 target = 3 个黑色像素 
- 规则 2 ,列 c = 1 的黑色像素分别位于行 0,行 1 和行 2。和行 r = 0 完全相同。

示例 2:

输入:picture = [["W","W","B"],["W","W","B"],["W","W","B"]], target = 1
输出:0

提示:

  • m == picture.length
  • n == picture[i].length
  • 1 <= m, n <= 200
  • picture[i][j] 为 'W' 或 'B'
  • 1 <= target <= min(m, n)
class Solution {
public:
    int findBlackPixel(vector<vector<char>>& picture, int target) {
        map<vector<char>,int>m;
        for(int i=0;i<picture.size();i++)m[picture[i]]=i;
        vector<int>r(picture.size(),0);
        vector<int>c(picture[0].size(),0);
        for(int i=0;i<picture.size();i++){
            for(int j=0;j<picture[0].size();j++){
                if(picture[i][j]=='B')r[i]++,c[j]++;
            }
        }
        int ans=0;
        for(int i=0;i<picture.size();i++){
            if(r[i]!=target)continue;
            if(m[picture[i]]!=i)continue;
            int sames=1;
            for(int k=0;k<i;k++){
                if(m[picture[k]]==i)sames++;
            }
            if(sames!=target)continue;
            for(int j=0;j<picture[0].size();j++){
                if(picture[i][j]=='B' && c[j]==target)ans+=target;
            }
        }
        return ans;
    }
};

535. TinyURL 的加密与解密

加解密 加解密_nameofcsdn的博客-CSDN博客

538. 把二叉搜索树转换为累加树

剑指 Offer II 054. 所有大于等于节点的值之和

539. 最小时间差

https://blog.csdn.net/nameofcsdn/article/details/119833252

540. 有序数组中的单一元素

二分、三分 二分、三分_nameofcsdn的博客-CSDN博客

542. 01 矩阵

BFS

545. 二叉树的边界

二叉树DFS

547. 省份数量

并查集

549. 二叉树最长连续序列 II

树形DP

552. 学生出勤记录 II

矩阵快速幂

553. 最优除法

区间DP

555. 分割连接字符串

给定一个字符串列表 strs,你可以将这些字符串连接成一个循环字符串,对于每个字符串,你可以选择是否翻转它。在所有可能的循环字符串中,你需要分割循环字符串(这将使循环字符串变成一个常规的字符串),然后找到字典序最大的字符串。

具体来说,要找到字典序最大的字符串,你需要经历两个阶段:

  1. 将所有字符串连接成一个循环字符串,你可以选择是否翻转某些字符串,并按照给定的顺序连接它们。
  2. 在循环字符串的某个位置分割它,这将使循环字符串从分割点变成一个常规的字符串。

你的工作是在所有可能的常规字符串中找到字典序最大的一个。

示例 1:

输入: strs = ["abc","xyz"]
输出: "zyxcba"
解释: 你可以得到循环字符串 "-abcxyz-", "-abczyx-", "-cbaxyz-", "-cbazyx-",其中 '-' 代表循环状态。 
答案字符串来自第四个循环字符串, 你可以从中间字符 'a' 分割开然后得到 "zyxcba"。

示例 2:

输入: strs = ["abc"]
输出: "cba"

提示:

  • 1 <= strs.length <= 1000
  • 1 <= strs[i].length <= 1000
  • 1 <= sum(strs[i].length) <= 1000
  • strs[i] 只包含小写英文字母

class Solution {
public:
	string splitLoopedString(vector<string>& strs) {
		string ans;
		for (auto &s : strs) {
			auto s2 = s;
			reverse(s.begin(), s.end());
			if (s < s2)s = s2;
			ans += s;
		}
		string ps = "";
		vector<string>pre{ "" }, post{ "" };
		for (int i = 0; i < strs.size() - 1; i++) {
			ps += strs[i];
			pre.push_back(ps);
		}
		ps = "";
		for (int i = strs.size() - 1; i > 0; i--) {
			ps = strs[i] + ps;
			post.push_back(ps);
		}
		for (int i = 0; i < strs.size(); i++) {
			string s = strs[i];
			vector<string>s1{ s,"" }, s2{ "",s };
			for (int i = 1; i < s.length(); i++) {
				s1.push_back(s.substr(i, s.length() - i));
				s2.push_back(s.substr(0, i));
			}
			reverse(s.begin(), s.end());
			s1.push_back(s), s2.push_back("");
			s1.push_back(""), s2.push_back(s);
			for (int i = 1; i < s.length(); i++) {
				s1.push_back(s.substr(i, s.length() - i));
				s2.push_back(s.substr(0, i));
			}
			for (int id = 0; id < s1.size();id++) {
				auto s = s1[id] + post[strs.size() - 1 - i] + pre[i] + s2[id];
				if (ans < s)ans = s;
			}
		}
		return ans;
	}
};

556. 下一个更大元素 III 

给定一个32位正整数 n,你需要找到最小的32位整数,其与 n 中存在的位数完全相同,并且其值大于n。如果不存在这样的32位整数,则返回-1。

示例 1:

输入: 12
输出: 21
示例 2:

输入: 21
输出: -1

class Solution {
public:
    int nextGreaterElement(int n) {
        char*sn;
        int len=IntToStr(n,10,sn);
        if(!next_permutation(sn,sn+len))return -1;
        long long res = StrToInt(sn,10);
        if(res==int(res))return res;
        return -1;
    }
};

559. N 叉树的最大深度

 多叉树

560. 和为K的子数组

剑指 Offer II 010. 和为 k 的子数组 https://blog.csdn.net/nameofcsdn/article/details/119833252

562. 矩阵中最长的连续1线段

给定一个 m x n 的二进制矩阵 mat ,返回矩阵中最长的连续1线段。

这条线段可以是水平的、垂直的、对角线的或者反对角线的。

示例 1:

输入: mat = [[0,1,1,0],[0,1,1,0],[0,0,0,1]]
输出: 3

示例 2:

输入: mat = [[1,1,1,1],[0,1,1,0],[0,0,0,1]]
输出: 4

提示:

  • m == mat.length
  • n == mat[i].length
  • 1 <= m, n <= 104
  • 1 <= m * n <= 104
  • mat[i][j] 不是 0 就是 1.
class Solution {
public:
    int longestLine(vector<vector<int>>& mat) {
        maxr = mat.size(),maxc = mat[0].size();
        vector<int>rs,cs;
        for(int i=0;i<mat[0].size();i++)rs.push_back(0),cs.push_back(i);
        int ans=longestLine(mat,rs,cs,1,0);
        rs.clear(),cs.clear();
        for(int i=0;i<mat.size();i++)rs.push_back(i),cs.push_back(0);
        ans=max(ans,longestLine(mat,rs,cs,0,1));
        for(int i=0;i<mat[0].size();i++)rs.push_back(0),cs.push_back(i);
        ans=max(ans,longestLine(mat,rs,cs,1,1));
        rs.clear(),cs.clear();
        for(int i=0;i<mat.size();i++)rs.push_back(i),cs.push_back(0);
        for(int i=0;i<mat[0].size();i++)rs.push_back(mat.size()-1),cs.push_back(i);
        ans=max(ans,longestLine(mat,rs,cs,-1,1));
        return ans;
    }
    int longestLine(vector<vector<int>>& mat, vector<int>rs,vector<int>cs,int dr,int dc) {
        int maxAns=0;
        for(int i=0;i<rs.size();i++){
            int r=rs[i],c=cs[i];
            vector<int>v;
            while(r>=0 && r<maxr && c>=0 && c<maxc){
                v.push_back(mat[r][c]);
                r+=dr,c+=dc;
            }
            maxAns=max(maxAns,longestLine(v));
        }
        return maxAns;
    }
    int longestLine(vector<int>v) {
        int s=0,ans=0;
        for(auto x:v){
            if(x==1)s++,ans=max(ans,s);
            else s=0;
        }
        return ans;
    }
    int maxr,maxc;
};

565. 数组嵌套

并查集

567. 字符串的排列

剑指 Offer II 014. 字符串中的变位词 https://blog.csdn.net/nameofcsdn/article/details/119833252

575. 分糖果

Alice 有 n 枚糖,其中第 i 枚糖的类型为 candyType[i] 。Alice 注意到她的体重正在增长,所以前去拜访了一位医生。

医生建议 Alice 要少摄入糖分,只吃掉她所有糖的 n / 2 即可(n 是一个偶数)。Alice 非常喜欢这些糖,她想要在遵循医生建议的情况下,尽可能吃到最多不同种类的糖。

给你一个长度为 n 的整数数组 candyType ,返回: Alice 在仅吃掉 n / 2 枚糖的情况下,可以吃到糖的 最多 种类数

示例 1:

输入:candyType = [1,1,2,2,3,3]
输出:3
解释:Alice 只能吃 6 / 2 = 3 枚糖,由于只有 3 种糖,她可以每种吃一枚。

示例 2:

输入:candyType = [1,1,2,3]
输出:2
解释:Alice 只能吃 4 / 2 = 2 枚糖,不管她选择吃的种类是 [1,2]、[1,3] 还是 [2,3],她只能吃到两种不同类的糖。

示例 3:

输入:candyType = [6,6,6,6]
输出:1
解释:Alice 只能吃 4 / 2 = 2 枚糖,尽管她能吃 2 枚,但只能吃到 1 种糖。

提示:

  • n == candyType.length
  • 2 <= n <= 104
  • n 是一个偶数
  • -105 <= candyType[i] <= 105
class Solution {
public:
    int distributeCandies(vector<int>& candyType) {
        set<int>s;
        for(auto x:candyType)s.insert(x);
        return min(s.size(),candyType.size()/2);
    }
};

581. 最短无序连续子数组

rust

589. N 叉树的前序遍历

 多叉树

590. N 叉树的后序遍历

 多叉树

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值