Merge branch 'master' of github.com:youngyangyang04/leetcode-master

This commit is contained in:
programmercarl 2024-03-14 12:10:06 +08:00
commit d3bfbbe658
111 changed files with 3295 additions and 326 deletions

View File

@ -133,6 +133,7 @@ public:
### Java
```java
//使用哈希表
public int[] twoSum(int[] nums, int target) {
int[] res = new int[2];
if(nums == null || nums.length == 0){
@ -151,6 +152,43 @@ public int[] twoSum(int[] nums, int target) {
return res;
}
```
```java
//使用双指针
public int[] twoSum(int[] nums, int target) {
int m=0,n=0,k,board=0;
int[] res=new int[2];
int[] tmp1=new int[nums.length];
//备份原本下标的nums数组
System.arraycopy(nums,0,tmp1,0,nums.length);
//将nums排序
Arrays.sort(nums);
//双指针
for(int i=0,j=nums.length-1;i<j;){
if(nums[i]+nums[j]<target)
i++;
else if(nums[i]+nums[j]>target)
j--;
else if(nums[i]+nums[j]==target){
m=i;
n=j;
break;
}
}
//找到nums[m]在tmp1数组中的下标
for(k=0;k<nums.length;k++){
if(tmp1[k]==nums[m]){
res[0]=k;
break;
}
}
//找到nums[n]在tmp1数组中的下标
for(int i=0;i<nums.length;i++){
if(tmp1[i]==nums[n]&&i!=k)
res[1]=i;
}
return res;
}
```
### Python
(版本一) 使用字典

View File

@ -618,7 +618,7 @@ char * longestPalindrome(char * s){
### C#
動態規則:
```c#
```csharp
public class Solution {
public string LongestPalindrome(string s) {
@ -648,7 +648,7 @@ public class Solution {
```
雙指針:
```C#
```csharp
public class Solution {
int maxlenth = 0;
int left = 0;

View File

@ -256,7 +256,7 @@ while (right > left) {
## 其他语言版本
### Java
(版本一) 双指针
```Java
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
@ -297,7 +297,43 @@ class Solution {
}
}
```
(版本二) 使用哈希集合
```Java
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
// 如果第一个元素大于零,不可能凑成三元组
if (nums[i] > 0) {
return result;
}
// 三元组元素a去重
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
HashSet<Integer> set = new HashSet<>();
for (int j = i + 1; j < nums.length; j++) {
// 三元组元素b去重
if (j > i + 2 && nums[j] == nums[j - 1] && nums[j - 1] == nums[j - 2]) {
continue;
}
int c = -nums[i] - nums[j];
if (set.contains(c)) {
result.add(Arrays.asList(nums[i], nums[j], c));
set.remove(c); // 三元组元素c去重
} else {
set.add(nums[j]);
}
}
}
return result;
}
}
```
### Python
(版本一) 双指针

View File

@ -733,7 +733,7 @@ def backtracking(result, letter_map, digits, path, index)
end
```
### C#
```C#
```csharp
public class Solution
{
public IList<string> res = new List<string>();

View File

@ -82,7 +82,7 @@ public:
// ListNode *tmp = slow->next; C++释放内存的逻辑
// slow->next = tmp->next;
// delete nth;
// delete tmp;
return dummyHead->next;
}

View File

@ -462,7 +462,7 @@ impl Solution {
```
### C#
```C#
```csharp
// 虚拟头结点
public ListNode SwapPairs(ListNode head)
{

View File

@ -425,8 +425,8 @@ public:
if (needle.size() == 0) {
return 0;
}
int next[needle.size()];
getNext(next, needle);
vector<int> next(needle.size());
getNext(&next[0], needle);
int j = -1; // // 因为next数组里记录的起始位置为-1
for (int i = 0; i < haystack.size(); i++) { // 注意i就从0开始
while(j >= 0 && haystack[i] != needle[j + 1]) { // 不匹配
@ -524,8 +524,8 @@ public:
if (needle.size() == 0) {
return 0;
}
int next[needle.size()];
getNext(next, needle);
vector<int> next(needle.size());
getNext(&next[0], needle);
int j = 0;
for (int i = 0; i < haystack.size(); i++) {
while(j > 0 && haystack[i] != needle[j]) {
@ -1359,7 +1359,7 @@ impl Solution {
```
>前缀表统一不减一
```C#
```csharp
public int StrStr(string haystack, string needle)
{
if (string.IsNullOrEmpty(needle))
@ -1428,4 +1428,3 @@ public int[] GetNext(string needle)
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -331,7 +331,7 @@ class Solution {
### C#
```c#
```csharp
public int[] SearchRange(int[] nums, int target) {
var leftBorder = GetLeftBorder(nums, target);

View File

@ -285,6 +285,34 @@ class Solution:
### Go
```go
/**
* @date: 2024 Jan 06
* @time: 13:44
* @author: Chris
**/
// 贪心算法优化版
// 记录步骤规则:每超过上一次可达最大范围,需要跳跃一次,次数+1
// 记录位置i == lastDistance + 1
func jump(nums []int) int {
// 根据题目规则初始位置为nums[0]
lastDistance := 0 // 上一次覆盖范围
curDistance := 0 // 当前覆盖范围(可达最大范围)
minStep := 0 // 记录最少跳跃次数
for i := 0; i < len(nums); i++ {
if i == lastDistance+1 { // 在上一次可达范围+1的位置记录步骤
minStep++ // 跳跃次数+1
lastDistance = curDistance // 记录时才可以更新
}
curDistance = max(nums[i]+i, curDistance) // 更新当前可达的最大范围
}
return minStep
}
```
```go
// 贪心版本一
func jump(nums []int) int {
@ -464,7 +492,34 @@ impl Solution {
}
}
```
### C
```c
#define max(a, b) ((a) > (b) ? (a) : (b))
int jump(int* nums, int numsSize) {
if(numsSize == 1){
return 0;
}
int count = 0;
// 记录当前能走的最远距离
int curDistance = 0;
// 记录下一步能走的最远距离
int nextDistance = 0;
for(int i = 0; i < numsSize; i++){
nextDistance = max(i + nums[i], nextDistance);
// 下标到了当前的最大距离
if(i == nextDistance){
count++;
curDistance = nextDistance;
}
}
return count;
}
```
### C#
```csharp
// 版本二
public class Solution
@ -490,3 +545,4 @@ public class Solution
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -230,7 +230,25 @@ class Solution:
```
### Go
贪心法
```go
func maxSubArray(nums []int) int {
max := nums[0]
count := 0
for i := 0; i < len(nums); i++{
count += nums[i]
if count > max{
max = count
}
if count < 0 {
count = 0
}
}
return max
}
```
动态规划
```go
func maxSubArray(nums []int) int {
maxSum := nums[0]

View File

@ -306,6 +306,47 @@ class Solution(object):
return result
```
版本二:定义四个边界
```python
class Solution(object):
def spiralOrder(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: List[int]
"""
if not matrix:
return []
rows = len(matrix)
cols = len(matrix[0])
top, bottom, left, right = 0, rows - 1, 0, cols - 1
print_list = []
while top <= bottom and left <= right:
# 从左到右
for i in range(left, right + 1):
print_list.append(matrix[top][i])
top += 1
# 从上到下
for i in range(top, bottom + 1):
print_list.append(matrix[i][right])
right -= 1
# 从右到左
if top <= bottom:
for i in range(right, left - 1, -1):
print_list.append(matrix[bottom][i])
bottom -= 1
# 从下到上
if left <= right:
for i in range(bottom, top - 1, -1):
print_list.append(matrix[i][left])
left += 1
return print_list
```
<p align="center">

View File

@ -336,9 +336,76 @@ impl Solution {
}
}
```
### C
```c
#define max(a, b) ((a) > (b) ? (a) : (b))
// 根据左边界进行排序
int cmp(const void * var1, const void * var2){
int *v1 = *(int **) var1;
int *v2 = *(int **) var2;
return v1[0] - v2[0];
}
int** merge(int** intervals, int intervalsSize, int* intervalsColSize, int* returnSize, int** returnColumnSizes) {
int ** result = malloc(sizeof (int *) * intervalsSize);
* returnColumnSizes = malloc(sizeof (int ) * intervalsSize);
for(int i = 0; i < intervalsSize; i++){
result[i] = malloc(sizeof (int ) * 2);
}
qsort(intervals, intervalsSize, sizeof (int *), cmp);
int count = 0;
for(int i = 0; i < intervalsSize; i++){
// 记录区间的左右边界
int L = intervals[i][0], R = intervals[i][1];
// 如果count为0或者前一区间的右区间小于此时的左边加入结果中
if (count == 0 || result[count - 1][1] < L) {
returnColumnSizes[0][count] = 2;
result[count][0] = L;
result[count][1] = R;
count++;
}
else{ // 更新右边界的值
result[count - 1][1] = max(R, result[count - 1][1]);
}
}
*returnSize = count;
return result;
}
```
### C#
```csharp
public class Solution
{
public int[][] Merge(int[][] intervals)
{
if (intervals.Length == 0)
return intervals;
Array.Sort(intervals, (a, b) => a[0] - b[0]);
List<List<int>> res = new List<List<int>>();
res.Add(intervals[0].ToList());
for (int i = 1; i < intervals.Length; i++)
{
if (res[res.Count - 1][1] >= intervals[i][0])
{
res[res.Count - 1][1] = Math.Max(res[res.Count - 1][1], intervals[i][1]);
}
else
{
res.Add(intervals[i].ToList());
}
}
return res.Select(x => x.ToArray()).ToArray();
}
}
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -87,11 +87,11 @@ public:
// 下面开始的四个for就是模拟转了一圈
// 模拟填充上行从左到右(左闭右开)
for (j = starty; j < n - offset; j++) {
res[startx][j] = count++;
for (j; j < n - offset; j++) {
res[i][j] = count++;
}
// 模拟填充右列从上到下(左闭右开)
for (i = startx; i < n - offset; i++) {
for (i; i < n - offset; i++) {
res[i][j] = count++;
}
// 模拟填充下行从右到左(左闭右开)
@ -138,42 +138,51 @@ public:
```Java
class Solution {
public int[][] generateMatrix(int n) {
int loop = 0; // 控制循环次数
int[][] res = new int[n][n];
int start = 0; // 每次循环的开始点(start, start)
int count = 1; // 定义填充数字
int i, j;
int[][] nums = new int[n][n];
int startX = 0, startY = 0; // 每一圈的起始点
int offset = 1;
int count = 1; // 矩阵中需要填写的数字
int loop = 1; // 记录当前的圈数
int i, j; // j 代表列, i 代表行;
while (loop++ < n / 2) { // 判断边界后loop从1开始
// 模拟上侧从左到右
for (j = start; j < n - loop; j++) {
res[start][j] = count++;
while (loop <= n / 2) {
// 顶部
// 左闭右开,所以判断循环结束时, j 不能等于 n - offset
for (j = startY; j < n - offset; j++) {
nums[startX][j] = count++;
}
// 模拟右侧从上到下
for (i = start; i < n - loop; i++) {
res[i][j] = count++;
// 右列
// 左闭右开,所以判断循环结束时, i 不能等于 n - offset
for (i = startX; i < n - offset; i++) {
nums[i][j] = count++;
}
// 模拟下侧从右到左
for (; j >= loop; j--) {
res[i][j] = count++;
// 底部
// 左闭右开,所以判断循环结束时, j != startY
for (; j > startY; j--) {
nums[i][j] = count++;
}
// 模拟左侧从下到上
for (; i >= loop; i--) {
res[i][j] = count++;
// 左列
// 左闭右开,所以判断循环结束时, i != startX
for (; i > startX; i--) {
nums[i][j] = count++;
}
start++;
startX++;
startY++;
offset++;
loop++;
}
if (n % 2 == 1) {
res[start][start] = count;
if (n % 2 == 1) { // n 为奇数时,单独处理矩阵中心的值
nums[startX][startY] = count;
}
return res;
return nums;
}
}
```
### python3:
@ -207,6 +216,50 @@ class Solution:
return nums
```
版本二:定义四个边界
```python
class Solution(object):
def generateMatrix(self, n):
if n <= 0:
return []
# 初始化 n x n 矩阵
matrix = [[0]*n for _ in range(n)]
# 初始化边界和起始值
top, bottom, left, right = 0, n-1, 0, n-1
num = 1
while top <= bottom and left <= right:
# 从左到右填充上边界
for i in range(left, right + 1):
matrix[top][i] = num
num += 1
top += 1
# 从上到下填充右边界
for i in range(top, bottom + 1):
matrix[i][right] = num
num += 1
right -= 1
# 从右到左填充下边界
for i in range(right, left - 1, -1):
matrix[bottom][i] = num
num += 1
bottom -= 1
# 从下到上填充左边界
for i in range(bottom, top - 1, -1):
matrix[i][left] = num
num += 1
left += 1
return matrix
```
### JavaScript:
```javascript

View File

@ -536,8 +536,29 @@ object Solution {
```
### c#
```csharp
// 二维数组
public class Solution
{
public int UniquePaths(int m, int n)
{
int[,] dp = new int[m, n];
for (int i = 0; i < m; i++) dp[i, 0] = 1;
for (int j = 0; j < n; j++) dp[0, j] = 1;
for (int i = 1; i < m; i++)
{
for (int j = 1; j < n; j++)
{
dp[i, j] = dp[i - 1, j] + dp[i, j - 1];
}
}
return dp[m - 1, n - 1];
}
}
```
```c#
```csharp
// 一维数组
public class Solution
{
public int UniquePaths(int m, int n)

View File

@ -734,6 +734,30 @@ object Solution {
}
}
```
### C#
```csharp
public class Solution
{
public int UniquePathsWithObstacles(int[][] obstacleGrid)
{
int m = obstacleGrid.Length;
int n = obstacleGrid[0].Length;
int[,] dp = new int[m, n];
if (obstacleGrid[0][0] == 1 || obstacleGrid[m - 1][n - 1] == 1) return 0;
for (int i = 0; i < m && obstacleGrid[i][0] == 0; i++) dp[i, 0] = 1;
for (int j = 0; j < n && obstacleGrid[0][j] == 0; j++) dp[0, j] = 1;
for (int i = 1; i < m; i++)
{
for (int j = 1; j < n; j++)
{
if (obstacleGrid[i][j] == 1) continue;
dp[i, j] = dp[i - 1, j] + dp[i, j - 1];
}
}
return dp[m - 1, n - 1];
}
}
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">

View File

@ -468,7 +468,7 @@ object Solution {
### C#
```c#
```csharp
public class Solution {
public int ClimbStairs(int n) {
if(n<=2) return n;

View File

@ -169,7 +169,32 @@ class climbStairs{
### Go
```go
func climbStairs(n int, m int) int {
dp := make([]int, n+1)
dp[0] = 1
for i := 1; i <= n; i++ {
for j := 1; j <= m; j++ {
if i-j >= 0 {
dp[i] += dp[i-j]
}
}
}
return dp[n]
}
func main() {
// 读取输入n,m
reader := bufio.NewReader(os.Stdin)
input, _ := reader.ReadString('\n')
input = strings.TrimSpace(input)
nv := strings.Split(input, " ")
n, _ := strconv.Atoi(nv[0])
m, _ := strconv.Atoi(nv[1])
result := climbStairs(n, m)
fmt.Println(result)
}
```
### JavaScript:

View File

@ -793,7 +793,7 @@ end
```
### C#
```C#
```csharp
// 暴力
public class Solution
{

View File

@ -158,13 +158,6 @@ public:
其实这道题目的知识点我们之前都讲过了如果之前讲过的子集问题和去重问题都掌握的好这道题目应该分分钟AC。
当然本题去重的逻辑,也可以这么写
```cpp
if (i > startIndex && nums[i] == nums[i - 1] ) {
continue;
}
```
## 其他语言版本
@ -641,7 +634,7 @@ object Solution {
}
```
### C#
```c#
```csharp
public class Solution
{
public IList<IList<int>> res = new List<IList<int>>();

View File

@ -328,6 +328,25 @@ object Solution {
}
}
```
### C#
```csharp
public class Solution
{
public int NumTrees(int n)
{
int[] dp = new int[n + 1];
dp[0] = 1;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= i; j++)
{
dp[i] += dp[j - 1] * dp[i - j];
}
}
return dp[n];
}
}
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">

View File

@ -792,7 +792,7 @@ impl Solution {
}
```
### C#
```C#
```csharp
// 递归
public long val = Int64.MinValue;
public bool IsValidBST(TreeNode root)

View File

@ -898,7 +898,7 @@ impl Solution {
}
```
### C#
```C#
```csharp
// 递归
public bool IsSymmetric(TreeNode root)
{

View File

@ -463,7 +463,7 @@ impl Solution {
}
```
### C#
```C#
```csharp
public IList<IList<int>> LevelOrder(TreeNode root)
{
var res = new List<IList<int>>();
@ -825,7 +825,7 @@ impl Solution {
}
```
### C#
```C#
```csharp
public IList<IList<int>> LevelOrderBottom(TreeNode root)
{
var res = new List<IList<int>>();

View File

@ -1033,7 +1033,10 @@ impl Solution {
}
```
### C#
```C#
0104.二叉树的最大深度
```csharp
// 递归法
public int MaxDepth(TreeNode root) {
if(root == null) return 0;
@ -1044,7 +1047,7 @@ public int MaxDepth(TreeNode root) {
return 1 + Math.Max(leftDepth, rightDepth);
}
```
```C#
```csharp
// 前序遍历
int result = 0;
public int MaxDepth(TreeNode root)
@ -1065,7 +1068,7 @@ public void GetDepth(TreeNode root, int depth)
return;
}
```
```C#
```csharp
// 迭代法
public int MaxDepth(TreeNode root)
{
@ -1088,7 +1091,76 @@ public int MaxDepth(TreeNode root)
}
```
559.n叉树的最大深度
递归法
```csharp
/*
递归法
*/
public class Solution {
public int MaxDepth(Node root) {
int res = 0;
/* 终止条件 */
if(root == null){
return 0;
}
/* logic */
// 遍历当前节点的子节点
for (int i = 0; i < root.children.Count; i++)
{
res = Math.Max(res, MaxDepth(root.children[i]));
}
return res + 1;
}
}
// @lc code=end
```
迭代法(层序遍历)
```csharp
/*
迭代法
*/
public class Solution
{
public int MaxDepth(Node root)
{
Queue<Node> que = new Queue<Node>(); // 使用泛型队列存储节点
int res = 0;
if(root != null){
que.Enqueue(root); // 将根节点加入队列
}
while (que.Count > 0)
{
int size = que.Count; // 获取当前层的节点数
res++; // 深度加一
for (int i = 0; i < size; i++)
{
// 每一层的遍历
var curNode = que.Dequeue(); // 取出队列中的节点
for (int j = 0; j < curNode.children.Count; j++)
{
if (curNode.children[j] != null)
{
que.Enqueue(curNode.children[j]); // 将子节点加入队列
}
}
}
}
return res; // 返回树的最大深度
}
}
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -1229,7 +1229,7 @@ impl Solution {
}
```
### C#
```C#
```csharp
public TreeNode BuildTree(int[] inorder, int[] postorder)
{
if (inorder.Length == 0 || postorder.Length == null) return null;

View File

@ -909,7 +909,7 @@ impl Solution {
}
```
### C#
```C#
```csharp
public bool IsBalanced(TreeNode root)
{
return GetHeight(root) == -1 ? false : true;

View File

@ -709,7 +709,7 @@ impl Solution {
}
```
### C#
```C#
```csharp
// 递归
public int MinDepth(TreeNode root)
{
@ -725,7 +725,7 @@ public int MinDepth(TreeNode root)
return res;
}
```
```C#
```csharp
// 迭代
public int MinDepth(TreeNode root)
{

View File

@ -1513,7 +1513,7 @@ impl Solution {
```
### C#
```C#
```csharp
// 0112.路径总和
// 递归
public bool HasPathSum(TreeNode root, int targetSum)
@ -1523,8 +1523,64 @@ public bool HasPathSum(TreeNode root, int targetSum)
return HasPathSum(root.left, targetSum - root.val) || HasPathSum(root.right, targetSum - root.val);
}
```
0113.路径总和:
```csharp
/*
* @lc app=leetcode id=113 lang=csharp
* 0113.路径总和 II
* [113] Path Sum II
* 递归法
*/
public class Solution {
private List<List<int>> result = new List<List<int>>();
private List<int> path = new List<int>();
// Main function to find paths with the given sum
public IList<IList<int>> PathSum(TreeNode root, int targetSum) {
result.Clear();
path.Clear();
if (root == null) return result.Select(list => list as IList<int>).ToList();
path.Add(root.val); // Add the root node to the path
traversal(root, targetSum - root.val); // Start the traversal
return result.Select(list => list as IList<int>).ToList();
}
// Recursive function to traverse the tree and find paths
private void traversal(TreeNode node, int count) {
// If a leaf node is reached and the target sum is achieved
if (node.left == null && node.right == null && count == 0) {
result.Add(new List<int>(path)); // Add a copy of the path to the result
return;
}
// If a leaf node is reached and the target sum is not achieved, or if it's not a leaf node
if (node.left == null && node.right == null) return;
// Traverse the left subtree
if (node.left != null) {
path.Add(node.left.val);
count -= node.left.val;
traversal(node.left, count); // Recursive call
count += node.left.val; // Backtrack
path.RemoveAt(path.Count - 1); // Backtrack
}
// Traverse the right subtree
if (node.right != null) {
path.Add(node.right.val);
count -= node.right.val;
traversal(node.right, count); // Recursive call
count += node.right.val; // Backtrack
path.RemoveAt(path.Count - 1); // Backtrack
}
}
}
// @lc code=end
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -358,7 +358,84 @@ function connect(root: NodePro | null): NodePro | null {
};
```
```csharp
//递归
public class Solution {
public Node Connect(Node root) {
if (root == null) {
return null;
}
ConnectNodes(root.left, root.right);
return root;
}
private void ConnectNodes(Node node1, Node node2) {
if (node1 == null || node2 == null) {
return;
}
// 将左子节点的 next 指向右子节点
node1.next = node2;
// 递归连接当前节点的左右子节点
ConnectNodes(node1.left, node1.right);
ConnectNodes(node2.left, node2.right);
// 连接跨越父节点的两个子树
ConnectNodes(node1.right, node2.left);
}
}
// 迭代
public class Solution
{
public Node Connect(Node root)
{
Queue<Node> que = new Queue<Node>();
if (root != null)
{
que.Enqueue(root);
}
while (que.Count > 0)
{
var queSize = que.Count;
for (int i = 0; i < queSize; i++)
{
var cur = que.Dequeue();
// 当这个节点不是这一层的最后的节点
if (i != queSize - 1)
{
// 当前节点指向下一个节点
cur.next = que.Peek();
}
// 否则指向空
else
{
cur.next = null;
}
if (cur.left != null)
{
que.Enqueue(cur.left);
}
if (cur.right != null)
{
que.Enqueue(cur.right);
}
}
}
return root;
}
}
```
<p align="center">

View File

@ -531,6 +531,52 @@ public class Solution
}
```
### C
> 贪心
```c
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) > (b) ? (b) : (a))
int maxProfit(int* prices, int pricesSize) {
int low = INT_MIN;
int result = 0;
for(int i = 0; i < pricesSize; i++){
low = min(low, prices[i]);
result = max(result, prices[i] - low);
}
return result;
}
```
> 动态规划
```c
#define max(a, b) ((a) > (b) ? (a) : (b))
int maxProfit(int* prices, int pricesSize){
if(pricesSize == 0){
return 0;
}
// dp初始化
int ** dp = malloc(sizeof (int *) * pricesSize);
for(int i = 0; i < pricesSize; i++){
dp[i] = malloc(sizeof (int ) * 2);
}
// 下标0表示持有股票的情况下的最大现金下标1表示不持有股票的情况下获得的最大现金
dp[0][0] = -prices[0];
dp[0][1] = 0;
for(int i = 1; i < pricesSize; i++){
dp[i][0] = max(dp[i - 1][0], - prices[i]);
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);
}
return dp[pricesSize - 1][1];
}
```
### Rust:
> 贪心
@ -568,4 +614,3 @@ impl Solution {
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -365,6 +365,49 @@ public class Solution
}
```
### C:
> 动态规划
```c
#define max(a, b) ((a) > (b) ? (a) : (b))
int maxProfit(int* prices, int pricesSize){
int **dp = malloc(sizeof (int *) * pricesSize);
for (int i = 0; i < pricesSize; ++i) {
dp[i] = malloc(sizeof (int ) * 2);
}
// 0表示持有该股票所得最大1表示不持有所得最大
dp[0][0] = -prices[0];
dp[0][1] = 0;
for (int i = 1; i < pricesSize; ++i) {
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]);
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);
}
return dp[pricesSize - 1][1];
}
```
> 贪心
```c
int maxProfit(int* prices, int pricesSize) {
if(pricesSize == 0){
return 0;
}
int result = 0;
for(int i = 1; i < pricesSize; i++){
// 如果今天股票价格大于昨天,代表有利润
if(prices[i] > prices[i - 1]){
result += prices[i] - prices[i - 1];
}
}
return result;
}
```
### Rust:
> 贪心
@ -416,3 +459,4 @@ impl Solution {
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -413,6 +413,34 @@ function maxProfit(prices: number[]): number {
};
```
### C:
```c
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) > (b) ? (b) : (a))
int maxProfit(int* prices, int pricesSize) {
int buy1 = prices[0], buy2 = prices[0];
int profit1 = 0, profit2 = 0;
for (int i = 0; i < pricesSize; ++i) {
// 寻找最低点买入
buy1 = min(buy1, prices[i]);
// 找到第一次交易的最大盈利,并不断维护这一最大值
profit1 = max(profit1, prices[i] - buy1);
// 寻找第二次交易的最低投资点,并且考虑前一次交易的成本
// 当前价格 - 第一次操作的盈利=新的投入成本(
// 为了让盈利最大,要寻找最小的成本)
buy2 = min(buy2, prices[i] - profit1);
// 第二次卖出后的盈利:当前价格减去成本,不断维护这一最大的总利润
profit2 = max(profit2, prices[i] - buy2);
}
return profit2;
}
```
### Rust
> 版本一
@ -465,4 +493,3 @@ impl Solution {
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -198,7 +198,7 @@ class Solution {
### Python
```
```python
class Solution:
def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
wordSet = set(wordList)

View File

@ -561,6 +561,237 @@ function solve(board) {
}
```
### Go
dfs:
```go
var DIRECTIONS = [4][2]int{{-1, 0}, {0, -1}, {1, 0}, {0, 1}}
func solve(board [][]byte) {
rows, cols := len(board), len(board[0])
// 列
for i := 0; i < rows; i++ {
if board[i][0] == 'O' {
dfs(board, i, 0)
}
if board[i][cols-1] == 'O' {
dfs(board, i, cols-1)
}
}
// 行
for j := 0; j < cols; j++ {
if board[0][j] == 'O' {
dfs(board, 0, j)
}
if board[rows-1][j] == 'O' {
dfs(board, rows-1, j)
}
}
for _, r := range board {
for j, c := range r {
if c == 'A' {
r[j] = 'O'
continue
}
if c == 'O' {
r[j] = 'X'
}
}
}
}
func dfs(board [][]byte, i, j int) {
board[i][j] = 'A'
for _, d := range DIRECTIONS {
x, y := i+d[0], j+d[1]
if x < 0 || x >= len(board) || y < 0 || y >= len(board[0]) {
continue
}
if board[x][y] == 'O' {
dfs(board, x, y)
}
}
}
```
bfs:
```go
var DIRECTIONS = [4][2]int{{-1, 0}, {0, -1}, {1, 0}, {0, 1}}
func solve(board [][]byte) {
rows, cols := len(board), len(board[0])
// 列
for i := 0; i < rows; i++ {
if board[i][0] == 'O' {
bfs(board, i, 0)
}
if board[i][cols-1] == 'O' {
bfs(board, i, cols-1)
}
}
// 行
for j := 0; j < cols; j++ {
if board[0][j] == 'O' {
bfs(board, 0, j)
}
if board[rows-1][j] == 'O' {
bfs(board, rows-1, j)
}
}
for _, r := range board {
for j, c := range r {
if c == 'A' {
r[j] = 'O'
continue
}
if c == 'O' {
r[j] = 'X'
}
}
}
}
func bfs(board [][]byte, i, j int) {
queue := [][]int{{i, j}}
board[i][j] = 'A'
for len(queue) > 0 {
cur := queue[0]
queue = queue[1:]
for _, d := range DIRECTIONS {
x, y := cur[0]+d[0], cur[1]+d[1]
if x < 0 || x >= len(board) || y < 0 || y >= len(board[0]) {
continue
}
if board[x][y] == 'O' {
board[x][y] = 'A'
queue = append(queue, []int{x, y})
}
}
}
}
```
### Rust
bfs:
```rust
impl Solution {
const DIRECTIONS: [(isize, isize); 4] = [(0, 1), (0, -1), (1, 0), (-1, 0)];
pub fn solve(board: &mut Vec<Vec<char>>) {
let (rows, cols) = (board.len(), board[0].len());
// 列
for i in 0..rows {
if board[i][0] == 'O' {
Self::dfs(board, i, 0);
}
if board[i][cols - 1] == 'O' {
Self::dfs(board, i, cols - 1);
}
}
//行
for j in 0..cols {
if board[0][j] == 'O' {
Self::dfs(board, 0, j);
}
if board[rows - 1][j] == 'O' {
Self::dfs(board, rows - 1, j);
}
}
for v in board.iter_mut() {
for c in v.iter_mut() {
if *c == 'A' {
*c = 'O';
continue;
}
if *c == 'O' {
*c = 'X';
}
}
}
}
pub fn dfs(board: &mut [Vec<char>], i: usize, j: usize) {
board[i][j] = 'A';
for (d1, d2) in Self::DIRECTIONS {
let (x, y) = (i as isize + d1, j as isize + d2);
if x < 0 || x >= board.len() as isize || y < 0 || y >= board[0].len() as isize {
continue;
}
let (x, y) = (x as usize, y as usize);
if board[x][y] == 'O' {
Self::dfs(board, x, y);
}
}
}
}
```
bfs:
```rust
use std::collections::VecDeque;
impl Solution {
const DIRECTIONS: [(isize, isize); 4] = [(0, 1), (0, -1), (1, 0), (-1, 0)];
pub fn solve(board: &mut Vec<Vec<char>>) {
let (rows, cols) = (board.len(), board[0].len());
// 列
for i in 0..rows {
if board[i][0] == 'O' {
Self::bfs(board, i, 0);
}
if board[i][cols - 1] == 'O' {
Self::bfs(board, i, cols - 1);
}
}
//行
for j in 0..cols {
if board[0][j] == 'O' {
Self::bfs(board, 0, j);
}
if board[rows - 1][j] == 'O' {
Self::bfs(board, rows - 1, j);
}
}
for v in board.iter_mut() {
for c in v.iter_mut() {
if *c == 'A' {
*c = 'O';
continue;
}
if *c == 'O' {
*c = 'X';
}
}
}
}
pub fn bfs(board: &mut [Vec<char>], i: usize, j: usize) {
let mut queue = VecDeque::from([(i, j)]);
board[i][j] = 'A';
while let Some((i, j)) = queue.pop_front() {
for (d1, d2) in Self::DIRECTIONS {
let (x, y) = (i as isize + d1, j as isize + d2);
if x < 0 || x >= board.len() as isize || y < 0 || y >= board[0].len() as isize {
continue;
}
let (x, y) = (x as usize, y as usize);
if board[x][y] == 'O' {
board[x][y] = 'A';
queue.push_back((x, y));
}
}
}
}
}
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>

View File

@ -498,6 +498,33 @@ function wordBreak(s: string, wordDict: string[]): boolean {
};
```
### C
```c
bool wordBreak(char* s, char** wordDict, int wordDictSize) {
int len = strlen(s);
// 初始化
bool dp[len + 1];
memset(dp, false, sizeof (dp));
dp[0] = true;
for (int i = 1; i < len + 1; ++i) {
for(int j = 0; j < wordDictSize; j++){
int wordLen = strlen(wordDict[j]);
// 分割点是由i和字典单词长度决定
int k = i - wordLen;
if(k < 0){
continue;
}
// 这里注意要限制长度故用strncmp
dp[i] = (dp[k] && !strncmp(s + k, wordDict[j], wordLen)) || dp[i];
}
}
return dp[len];
}
```
### Rust:
```rust
@ -521,4 +548,3 @@ impl Solution {
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -973,7 +973,7 @@ char * reverseWords(char * s){
```
### C#
```C# LINQ高级方法
```csharp LINQ高级方法
public string ReverseWords(string s) {
return string.Join(' ', s.Trim().Split(' ',StringSplitOptions.RemoveEmptyEntries).Reverse());
}

View File

@ -474,6 +474,34 @@ function maxProfit(k: number, prices: number[]): number {
};
```
### C:
```c
#define max(a, b) ((a) > (b) ? (a) : (b))
int maxProfit(int k, int* prices, int pricesSize) {
if(pricesSize == 0){
return 0;
}
int dp[pricesSize][2 * k + 1];
memset(dp, 0, sizeof(int) * pricesSize * (2 * k + 1));
for (int j = 1; j < 2 * k; j += 2) {
dp[0][j] = -prices[0];
}
for (int i = 1;i < pricesSize; i++) {//枚举股票
for (int j = 0; j < 2 * k - 1; j += 2) { //更新每一次买入卖出
dp[i][j + 1] = max(dp[i - 1][j + 1], dp[i - 1][j] - prices[i]);
dp[i][j + 2] = max(dp[i - 1][j + 2], dp[i - 1][j + 1] + prices[i]);
}
}
return dp[pricesSize - 1][2 * k];
}
```
### Rust
```rust
@ -529,3 +557,4 @@ impl Solution {
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -315,6 +315,31 @@ function rob(nums: number[]): number {
};
```
### C
```c
#define max(a, b) ((a) > (b) ? (a) : (b))
int rob(int* nums, int numsSize) {
if(numsSize == 0){
return 0;
}
if(numsSize == 1){
return nums[0];
}
// dp初始化
int dp[numsSize];
dp[0] = nums[0];
dp[1] = max(nums[0], nums[1]);
for(int i = 2; i < numsSize; i++){
dp[i] = max(dp[i - 1], dp[i - 2] + nums[i]);
}
return dp[numsSize - 1];
}
```
### Rust:
```rust
@ -339,3 +364,4 @@ impl Solution {
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -199,7 +199,9 @@ class Solution {
### Python
BFS solution
```python
class Solution:
def __init__(self):
@ -240,6 +242,7 @@ class Solution:
```
### JavaScript
```javascript
var numIslands = function (grid) {
let dir = [[0, 1], [1, 0], [-1, 0], [0, -1]]; // 四个方向
@ -321,11 +324,53 @@ function numIslands2(grid: string[][]): number {
}
```
### Go
```go
var DIRECTIONS = [4][2]int{{-1, 0}, {0, -1}, {1, 0}, {0, 1}}
func numIslands(grid [][]byte) int {
res := 0
visited := make([][]bool, len(grid))
for i := 0; i < len(grid); i++ {
visited[i] = make([]bool, len(grid[0]))
}
for i, rows := range grid {
for j, v := range rows {
if v == '1' && !visited[i][j] {
res++
bfs(grid, visited, i, j)
}
}
}
return res
}
func bfs(grid [][]byte, visited [][]bool, i, j int) {
queue := [][2]int{{i, j}}
visited[i][j] = true // 标记已访问,循环中标记会导致重复
for len(queue) > 0 {
cur := queue[0]
queue = queue[1:]
for _, d := range DIRECTIONS {
x, y := cur[0]+d[0], cur[1]+d[1]
if x < 0 || x >= len(grid) || y < 0 || y >= len(grid[0]) {
continue
}
if grid[x][y] == '1' && !visited[x][y] {
visited[x][y] = true
queue = append(queue, [2]int{x, y})
}
}
}
}
```
### Rust
```rust
use std::collections::VecDeque;
impl Solution {
const DIRECTIONS: [(i32, i32); 4] = [(0, 1), (1, 0), (-1, 0), (0, -1)];

View File

@ -37,7 +37,7 @@
在遇到标记过的陆地节点和海洋节点的时候直接跳过。 这样计数器就是最终岛屿的数量。
那么如把节点陆地所能遍历到的陆地都标记上呢,就可以使用 DFSBFS或者并查集。
那么如把节点陆地所能遍历到的陆地都标记上呢,就可以使用 DFSBFS或者并查集。
### 深度优先搜索
@ -389,50 +389,41 @@ function numIslands(grid: string[][]): number {
### Go
```go
var DIRECTIONS = [4][2]int{{-1, 0}, {0, -1}, {1, 0}, {0, 1}}
func numIslands(grid [][]byte) int {
// 用1标记已访问
visited := make([][]int, len(grid))
for i := 0; i < len(visited); i++{
visited[i] = make([]int, len(grid[0]))
}
res := 0
var bfs func(x, y int)
bfs = func(x, y int){
stack := make([][]int, 0)
stack = append(stack, []int{x, y})
moveX := []int{1, -1, 0, 0}
moveY := []int{0, 0, 1, -1}
visited := make([][]bool, len(grid))
for i := 0; i < len(grid); i++ {
visited[i] = make([]bool, len(grid[0]))
}
for len(stack) != 0{
node := stack[len(stack) - 1]
stack = stack[:len(stack) - 1]
for i, rows := range grid {
for j, v := range rows {
if v == '1' && !visited[i][j] {
res++
dfs(grid, visited, i, j)
}
}
}
for i := 0; i < 4; i++{
dx := moveX[i] + node[0]
dy := moveY[i] + node[1]
if dx < 0 || dx >= len(grid) || dy < 0 || dy >= len(grid[0]) || visited[dx][dy] == 1{
continue
}
visited[dx][dy] = 1
if grid[dx][dy] == '1'{
stack = append(stack, []int{dx,dy})
}
}
}
}
return res
}
result := 0
for i := 0; i < len(grid); i++{
for j := 0; j < len(grid[0]); j++{
if visited[i][j] == 0 && grid[i][j] == '1'{
bfs(i, j)
visited[i][j] = 1
result++
}
}
}
func dfs(grid [][]byte, visited [][]bool, i, j int) {
visited[x][y] = true
for _, d := range DIRECTIONS {
x, y := i+d[0], j+d[1]
if x < 0 || x >= len(grid) || y < 0 || y >= len(grid[0]) {
continue
}
if grid[x][y] == '1' && !visited[x][y] {
dfs(grid, visited, x, y)
}
}
return result
}
```

View File

@ -308,6 +308,34 @@ function robRange(nums: number[], start: number, end: number): number {
}
```
### C
```c
#define max(a, b) ((a) > (b) ? (a) : (b))
// 198.打家劫舍的逻辑
int robRange(int* nums, int start, int end, int numsSize) {
if (end == start) return nums[start];
int dp[numsSize];
dp[start] = nums[start];
dp[start + 1] = max(nums[start], nums[start + 1]);
for (int i = start + 2; i <= end; i++) {
dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);
}
return dp[end];
}
int rob(int* nums, int numsSize) {
if (numsSize == 0) return 0;
if (numsSize == 1) return nums[0];
int result1 = robRange(nums, 0, numsSize - 2, numsSize); // 情况二
int result2 = robRange(nums, 1, numsSize - 1, numsSize); // 情况三
return max(result1, result2);
}
```
### Rust:
```rust
@ -343,4 +371,3 @@ impl Solution {
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -868,7 +868,7 @@ impl Solution {
}
```
### C#
```C#
```csharp
// 递归
public int CountNodes(TreeNode root)
{

View File

@ -1046,6 +1046,8 @@ class MyStack() {
### C#:
> 双队列
```csharp
public class MyStack {
Queue<int> queue1;
@ -1080,6 +1082,54 @@ public class MyStack {
}
```
> 单队列
```c#
/*
* @lc app=leetcode id=225 lang=csharp
* 版本二:单队列
* [225] Implement Stack using Queues
*/
// @lc code=start
public class MyStack {
Queue<int> myQueue;
public MyStack() {
myQueue = new Queue<int>();
}
public void Push(int x) {
myQueue.Enqueue(x);
}
//使用一个队列实现
public int Pop() {
//一个队列在模拟栈弹出元素的时候只要将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部,此时再去弹出元素就是栈的顺序了。
for (var i = 0; i < myQueue.Count-1; i++)
{
myQueue.Enqueue(myQueue.Dequeue());
}
return myQueue.Dequeue();
}
//复用Pop()的代码
public int Top() {
int res = Pop();
myQueue.Enqueue(res);
return res;
}
public bool Empty() {
return (myQueue.Count == 0);
}
}
// @lc code=end
```
### PHP:
> 双队列
@ -1203,3 +1253,4 @@ impl MyStack {
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -298,7 +298,7 @@ class Solution:
return self.traversal(root, p, q)
```
迭代法(版本二)精简
递归法(版本二)精简
```python
class Solution:
def lowestCommonAncestor(self, root, p, q):
@ -521,7 +521,7 @@ impl Solution {
}
```
### C#
```C#
```csharp
// 递归
public TreeNode LowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q)
{

View File

@ -432,7 +432,7 @@ impl Solution {
}
```
### C#
```C#
```csharp
public TreeNode LowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q)
{
if (root == null || root == p || root == q) return root;

View File

@ -901,7 +901,7 @@ impl Solution {
}
```
### C#
```C#
```csharp
public IList<string> BinaryTreePaths(TreeNode root)
{
List<int> path = new();

View File

@ -389,6 +389,30 @@ function numSquares(n: number): number {
};
```
## C
```c
#define min(a, b) ((a) > (b) ? (b) : (a))
int numSquares(int n) {
int* dp = (int*)malloc(sizeof(int) * (n + 1));
for (int j = 0; j < n + 1; j++) {
dp[j] = INT_MAX;
}
dp[0] = 0;
// 遍历背包
for (int i = 0; i <= n; ++i) {
// 遍历物品
for (int j = 1; j * j <= i; ++j) {
dp[i] = min(dp[i - j * j] + 1, dp[i]);
}
}
return dp[n];
}
```
### Rust:
```rust
@ -439,4 +463,3 @@ impl Solution {
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -288,6 +288,36 @@ function lengthOfLIS(nums: number[]): number {
};
```
### C:
```c
#define max(a, b) ((a) > (b) ? (a) : (b))
int lengthOfLIS(int* nums, int numsSize) {
if(numsSize <= 1){
return numsSize;
}
int dp[numsSize];
for(int i = 0; i < numsSize; i++){
dp[i]=1;
}
int result = 1;
for (int i = 1; i < numsSize; ++i) {
for (int j = 0; j < i; ++j) {
if(nums[i] > nums[j]){
dp[i] = max(dp[i], dp[j] + 1);
}
if(dp[i] > result){
result = dp[i];
}
}
}
return result;
}
```
### Rust:
```rust
@ -311,4 +341,3 @@ pub fn length_of_lis(nums: Vec<i32>) -> i32 {
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -457,6 +457,40 @@ function maxProfit(prices: number[]): number {
};
```
### C:
```c
#define max(a, b) ((a) > (b) ? (a) : (b))
/**
* 状态一:持有股票状态(今天买入股票,
* 或者是之前就买入了股票然后没有操作,一直持有)
* 不持有股票状态,这里就有两种卖出股票状态
* 状态二:保持卖出股票的状态(两天前就卖出了股票,度过一天冷冻期。
* 或者是前一天就是卖出股票状态,一直没操作)
* 状态三:今天卖出股票
* 状态四:今天为冷冻期状态,但冷冻期状态不可持续,只有一天!
*/
int maxProfit(int* prices, int pricesSize) {
if(pricesSize == 0){
return 0;
}
int dp[pricesSize][4];
memset(dp, 0, sizeof (int ) * pricesSize * 4);
dp[0][0] = -prices[0];
for (int i = 1; i < pricesSize; ++i) {
dp[i][0] = max(dp[i - 1][0], max(dp[i - 1][1] - prices[i], dp[i - 1][3] - prices[i]));
dp[i][1] = max(dp[i - 1][1], dp[i - 1][3]);
dp[i][2] = dp[i - 1][0] + prices[i];
dp[i][3] = dp[i - 1][2];
}
return max(dp[pricesSize - 1][1], max(dp[pricesSize - 1][2], dp[pricesSize - 1][3]));
}
```
### Rust
```rust
@ -486,4 +520,3 @@ impl Solution {
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -352,6 +352,35 @@ func min(a, b int) int {
```
## C
```c
#define min(a, b) ((a) > (b) ? (b) : (a))
int coinChange(int* coins, int coinsSize, int amount) {
int* dp = (int*)malloc(sizeof(int) * (amount + 1));
for (int j = 0; j < amount + 1; j++) {
dp[j] = INT_MAX;
}
dp[0] = 0;
// 遍历背包
for(int i = 0; i <= amount; i++){
// 遍历物品
for(int j = 0; j < coinsSize; j++){
if(i - coins[j] >= 0 && dp[i - coins[j]] != INT_MAX){
dp[i] = min(dp[i], dp[i - coins[j]] + 1);
}
}
}
if(dp[amount] == INT_MAX){
return -1;
}
return dp[amount];
}
```
### Rust:
```rust
@ -474,4 +503,3 @@ function coinChange(coins: number[], amount: number): number {
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -449,34 +449,37 @@ class Solution:
```
回溯 使用字典
```python
from collections import defaultdict
class Solution:
def findItinerary(self, tickets: List[List[str]]) -> List[str]:
targets = defaultdict(list) # 构建机场字典
for ticket in tickets:
targets[ticket[0]].append(ticket[1])
for airport in targets:
targets[airport].sort() # 对目的地列表进行排序
self.adj = {}
path = ["JFK"] # 起始机场为"JFK"
self.backtracking(targets, path, len(tickets))
return path
# sort by the destination alphabetically
# 根据航班每一站的重点字母顺序排序
tickets.sort(key=lambda x:x[1])
def backtracking(self, targets, path, ticketNum):
if len(path) == ticketNum + 1:
return True # 找到有效行程
# get all possible connection for each destination
# 罗列每一站的下一个可选项
for u,v in tickets:
if u in self.adj: self.adj[u].append(v)
else: self.adj[u] = [v]
airport = path[-1] # 当前机场
destinations = targets[airport] # 当前机场可以到达的目的地列表
for i, dest in enumerate(destinations):
targets[airport].pop(i) # 标记已使用的机票
path.append(dest) # 添加目的地到路径
if self.backtracking(targets, path, ticketNum):
return True # 找到有效行程
targets[airport].insert(i, dest) # 回溯,恢复机票
path.pop() # 移除目的地
return False # 没有找到有效行程
# 从JFK出发
self.result = []
self.dfs("JFK") # start with JFK
return self.result[::-1] # reverse to get the result
def dfs(self, s):
# if depart city has flight and the flight can go to another city
while s in self.adj and len(self.adj[s]) > 0:
# 找到s能到哪里选能到的第一个机场
v = self.adj[s][0] # we go to the 1 choice of the city
# 在之后的可选项机场中去掉这个机场
self.adj[s].pop(0) # get rid of this choice since we used it
# 从当前的新出发点开始
self.dfs(v) # we start from the new airport
self.result.append(s) # after append, it will back track to last node, thus the result list is in reversed order
```
回溯 使用字典 逆序

View File

@ -490,6 +490,33 @@ function robNode(node: TreeNode | null): MaxValueArr {
}
```
### C
```c
int *robTree(struct TreeNode *node) {
int* amounts = (int*) malloc(sizeof(int) * 2);
memset(amounts, 0, sizeof(int) * 2);
if(node == NULL){
return amounts;
}
int * left = robTree(node->left);
int * right = robTree(node->right);
// 偷当前节点
amounts[1] = node->val + left[0] + right[0];
// 不偷当前节点
amounts[0] = max(left[0], left[1]) + max(right[0], right[1]);
return amounts;
}
int rob(struct TreeNode* root) {
int * dp = robTree(root);
// 0代表不偷当前节点可以获得的最大值1表示偷当前节点可以获取的最大值
return max(dp[0], dp[1]);
}
```
### Rust
动态规划:
@ -523,4 +550,3 @@ impl Solution {
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -496,6 +496,25 @@ class Solution {
}
}
```
### C#
```csharp
public class Solution
{
public int IntegerBreak(int n)
{
int[] dp = new int[n + 1];
dp[2] = 1;
for (int i = 3; i <= n; i++)
{
for (int j = 1; j <= i / 2; j++)
{
dp[i] = Math.Max(dp[i],Math.Max(j*(i-j),j*dp[i-j]));
}
}
return dp[n];
}
}
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">

View File

@ -324,6 +324,34 @@ func topKFrequent(nums []int, k int) []int {
### JavaScript:
解法一:
Leetcode 提供了优先队列的库,具体文档可以参见 [@datastructures-js/priority-queue](https://github.com/datastructures-js/priority-queue/blob/v5/README.md)。
```js
var topKFrequent = function (nums, k) {
const map = new Map();
const res = [];
//使用 map 统计元素出现频率
for (const num of nums) {
map.set(num, (map.get(num) || 0) + 1);
}
//创建小顶堆
const heap = new PriorityQueue({
compare: (a, b) => a.value - b.value
})
for (const [key, value] of map) {
heap.enqueue({ key, value });
if (heap.size() > k) heap.dequeue();
}
//处理输出
while (heap.size()) res.push(heap.dequeue().key);
return res;
};
```
解法二:
手写实现优先队列
```js
// js 没有堆 需要自己构造
class Heap {

View File

@ -231,6 +231,8 @@ class Solution:
### Go
(版本一)使用字典和集合
```go
func intersection(nums1 []int, nums2 []int) []int {
set:=make(map[int]struct{},0) // 用map模拟set
@ -251,6 +253,28 @@ func intersection(nums1 []int, nums2 []int) []int {
}
```
(版本二)使用数组
```go
func intersection(nums1 []int, nums2 []int) []int {
count1 := make([]int, 1001, 1001)
count2 := make([]int, 1001, 1001)
res := make([]int, 0)
for _, v := range nums1 {
count1[v] = 1
}
for _, v := range nums2 {
count2[v] = 1
}
for i := 0; i <= 1000; i++ {
if count1[i] + count2[i] == 2 {
res = append(res, i)
}
}
return res
}
```
### JavaScript:
```js

View File

@ -312,10 +312,52 @@ impl Solution {
}
}
```
### C
```c
int combinationSum4(int* nums, int numsSize, int target) {
int dp[target + 1];
memset(dp, 0, sizeof (dp ));
dp[0] = 1;
for(int i = 0; i <= target; i++){
for(int j = 0; j < numsSize; j++){
if(i - nums[j] >= 0 && dp[i] < INT_MAX - dp[i - nums[j]]){
dp[i] += dp[i - nums[j]];
}
}
}
return dp[target];
}
```
### C#
```csharp
public class Solution
{
public int CombinationSum4(int[] nums, int target)
{
int[] dp = new int[target + 1];
dp[0] = 1;
for (int i = 0; i <= target; i++)
{
for (int j = 0; j < nums.Length; j++)
{
if (i >= nums[j] && dp[i] < int.MaxValue - dp[i - nums[j]])
{
dp[i] += dp[i - nums[j]];
}
}
}
return dp[target];
}
}
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -216,7 +216,7 @@ class Solution:
(版本六使用count(简单易懂)
```python3
```python
class Solution:
def canConstruct(self, ransomNote: str, magazine: str) -> bool:
for char in ransomNote:
@ -445,6 +445,25 @@ public bool CanConstruct(string ransomNote, string magazine) {
return true;
}
```
### C
```c
bool canConstruct(char* ransomNote, char* magazine) {
// 定义哈希映射数组
int hashmap[26] = {0};
// 对magazine中字符计数
while (*magazine != '\0') hashmap[*magazine++ % 26]++;
// 遍历ransomNote对应的字符自减小于0说明该字符magazine没有或不足够表示
while (*ransomNote != '\0') hashmap[*ransomNote++ % 26]--;
// 如果数组中存在负数说明ransomNote不能由magazine里面的字符构成
for (int i = 0; i < 26; i++) {
if (hashmap[i] < 0) return false;
}
return true;
}
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">

View File

@ -652,7 +652,7 @@ impl Solution {
}
```
### C#
```C#
```csharp
// 递归
public int SumOfLeftLeaves(TreeNode root)
{

View File

@ -396,6 +396,29 @@ object Solution {
}
}
```
### C#
```csharp
public class Solution
{
public int[][] ReconstructQueue(int[][] people)
{
Array.Sort(people, (a, b) =>
{
if (a[0] == b[0])
{
return a[1] - b[1];
}
return b[0] - a[0];
});
var res = new List<int[]>();
for (int i = 0; i < people.Length; i++)
{
res.Insert(people[i][1], people[i]);
}
return res.ToArray();
}
}
```
<p align="center">

View File

@ -726,7 +726,35 @@ object Solution {
}
}
```
### C#
```csharp
public class Solution
{
public bool CanPartition(int[] nums)
{
int sum = 0;
int[] dp = new int[10001];
foreach (int num in nums)
{
sum += num;
}
if (sum % 2 == 1) return false;
int tartget = sum / 2;
for (int i = 0; i < nums.Length; i++)
{
for (int j = tartget; j >= nums[i]; j--)
{
dp[j] = Math.Max(dp[j], dp[j - nums[i]] + nums[i]);
}
}
if (dp[tartget] == tartget)
return true;
return false;
}
}
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>

View File

@ -562,7 +562,213 @@ function pacificAtlantic(heights) {
}
```
### go
dfs:
```go
var DIRECTIONS = [4][2]int{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}
func pacificAtlantic(heights [][]int) [][]int {
res := make([][]int, 0)
pacific := make([][]bool, len(heights))
atlantic := make([][]bool, len(heights))
for i := 0; i < len(heights); i++ {
pacific[i] = make([]bool, len(heights[0]))
atlantic[i] = make([]bool, len(heights[0]))
}
// 列
for i := 0; i < len(heights); i++ {
dfs(heights, pacific, i, 0)
dfs(heights, atlantic, i, len(heights[0])-1)
}
// 行
for j := 0; j < len(heights[0]); j++ {
dfs(heights, pacific, 0, j)
dfs(heights, atlantic, len(heights)-1, j)
}
for i := 0; i < len(heights); i++ {
for j := 0; j < len(heights[0]); j++ {
if pacific[i][j] && atlantic[i][j] {
res = append(res, []int{i, j})
}
}
}
return res
}
func dfs(heights [][]int, visited [][]bool, i, j int) {
visited[i][j] = true
for _, d := range DIRECTIONS {
x, y := i+d[0], j+d[1]
if x < 0 || x >= len(heights) || y < 0 || y >= len(heights[0]) || heights[i][j] > heights[x][y] || visited[x][y] {
continue
}
dfs(heights, visited, x, y)
}
}
```
bfs:
```go
var DIRECTIONS = [4][2]int{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}
func pacificAtlantic(heights [][]int) [][]int {
res := make([][]int, 0)
pacific := make([][]bool, len(heights))
atlantic := make([][]bool, len(heights))
for i := 0; i < len(heights); i++ {
pacific[i] = make([]bool, len(heights[0]))
atlantic[i] = make([]bool, len(heights[0]))
}
// 列
for i := 0; i < len(heights); i++ {
bfs(heights, pacific, i, 0)
bfs(heights, atlantic, i, len(heights[0])-1)
}
// 行
for j := 0; j < len(heights[0]); j++ {
bfs(heights, pacific, 0, j)
bfs(heights, atlantic, len(heights)-1, j)
}
for i := 0; i < len(heights); i++ {
for j := 0; j < len(heights[0]); j++ {
if pacific[i][j] && atlantic[i][j] {
res = append(res, []int{i, j})
}
}
}
return res
}
func bfs(heights [][]int, visited [][]bool, i, j int) {
queue := make([][]int, 0)
queue = append(queue, []int{i, j})
visited[i][j] = true
for len(queue) > 0 {
cur := queue[0]
queue = queue[1:]
for _, d := range DIRECTIONS {
x, y := cur[0]+d[0], cur[1]+d[1]
if x < 0 || x >= len(heights) || y < 0 || y >= len(heights[0]) || heights[cur[0]][cur[1]] > heights[x][y] || visited[x][y] {
continue
}
queue = append(queue, []int{x, y})
visited[x][y] = true
}
}
}
```
### Rust
dfs:
```rust
impl Solution {
const DIRECTIONS: [(isize, isize); 4] = [(0, 1), (0, -1), (1, 0), (-1, 0)];
pub fn pacific_atlantic(heights: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
let (m, n) = (heights.len(), heights[0].len());
let mut res = vec![];
let (mut pacific, mut atlantic) = (vec![vec![false; n]; m], vec![vec![false; n]; m]);
// 列
for i in 0..m {
Self::dfs(&heights, &mut pacific, i, 0);
Self::dfs(&heights, &mut atlantic, i, n - 1);
}
for j in 0..n {
Self::dfs(&heights, &mut pacific, 0, j);
Self::dfs(&heights, &mut atlantic, m - 1, j);
}
for i in 0..m {
for j in 0..n {
if pacific[i][j] && atlantic[i][j] {
res.push(vec![i as i32, j as i32]);
}
}
}
res
}
pub fn dfs(heights: &[Vec<i32>], visited: &mut [Vec<bool>], i: usize, j: usize) {
visited[i][j] = true;
for (dx, dy) in Self::DIRECTIONS {
let (x, y) = (i as isize + dx, j as isize + dy);
if x < 0 || x >= heights.len() as isize || y < 0 || y >= heights[0].len() as isize {
continue;
}
let (x, y) = (x as usize, y as usize);
if !visited[x][y] && heights[x][y] >= heights[i][j] {
Self::dfs(heights, visited, x, y);
}
}
}
}
```
bfs:
```rust
use std::collections::VecDeque;
impl Solution {
const DIRECTIONS: [(isize, isize); 4] = [(0, 1), (0, -1), (1, 0), (-1, 0)];
pub fn pacific_atlantic(heights: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
let (m, n) = (heights.len(), heights[0].len());
let mut res = vec![];
let (mut pacific, mut atlantic) = (vec![vec![false; n]; m], vec![vec![false; n]; m]);
// 列
for i in 0..m {
Self::bfs(&heights, &mut pacific, i, 0);
Self::bfs(&heights, &mut atlantic, i, n - 1);
}
for j in 0..n {
Self::bfs(&heights, &mut pacific, 0, j);
Self::bfs(&heights, &mut atlantic, m - 1, j);
}
for i in 0..m {
for j in 0..n {
if pacific[i][j] && atlantic[i][j] {
res.push(vec![i as i32, j as i32]);
}
}
}
res
}
pub fn bfs(heights: &[Vec<i32>], visited: &mut [Vec<bool>], i: usize, j: usize) {
let mut queue = VecDeque::from([(i, j)]);
visited[i][j] = true;
while let Some((i, j)) = queue.pop_front() {
for (dx, dy) in Self::DIRECTIONS {
let (x, y) = (i as isize + dx, j as isize + dy);
if x < 0 || x >= heights.len() as isize || y < 0 || y >= heights[0].len() as isize {
continue;
}
let (x, y) = (x as usize, y as usize);
if !visited[x][y] && heights[x][y] >= heights[i][j] {
queue.push_back((x, y));
visited[x][y] = true;
}
}
}
}
}
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">

View File

@ -423,7 +423,7 @@ object Solution {
```Rust
impl Solution {
pub fn erase_overlap_intervals(intervals: Vec<Vec<i32>>) -> i32 {
pub fn erase_overlap_intervals(mut intervals: Vec<Vec<i32>>) -> i32 {
if intervals.is_empty() {
return 0;
}
@ -441,6 +441,57 @@ impl Solution {
}
}
```
### C
```c
// 按照区间右边界排序
int cmp(const void * var1, const void * var2){
return (*(int **) var1)[1] - (*(int **) var2)[1];
}
int eraseOverlapIntervals(int** intervals, int intervalsSize, int* intervalsColSize) {
if(intervalsSize == 0){
return 0;
}
qsort(intervals, intervalsSize, sizeof (int *), cmp);
// 记录非重叠的区间数量
int count = 1;
// 记录区间分割点
int end = intervals[0][1];
for(int i = 1; i < intervalsSize; i++){
if(end <= intervals[i][0]){
end = intervals[i][1];
count++;
}
}
return intervalsSize - count;
}
```
### C#
```csharp
public class Solution
{
public int EraseOverlapIntervals(int[][] intervals)
{
if (intervals.Length == 0) return 0;
Array.Sort(intervals, (a, b) => a[1].CompareTo(b[1]));
int res = 1, end = intervals[0][1];
for (int i = 1; i < intervals.Length; i++)
{
if (end <= intervals[i][0])
{
end = intervals[i][1];
res++;
}
}
return intervals.Length - res;
}
}
```
<p align="center">

View File

@ -42,7 +42,7 @@
代码如下:
```
```cpp
TreeNode* deleteNode(TreeNode* root, int key)
```
@ -50,7 +50,7 @@ TreeNode* deleteNode(TreeNode* root, int key)
遇到空返回,其实这也说明没找到删除的节点,遍历到空节点直接返回了
```
```cpp
if (root == nullptr) return root;
```
@ -106,7 +106,7 @@ if (root->val == key) {
这里相当于把新的节点返回给上一层,上一层就要用 root->left 或者 root->right接住代码如下
```
```cpp
if (root->val > key) root->left = deleteNode(root->left, key);
if (root->val < key) root->right = deleteNode(root->right, key);
return root;
@ -772,7 +772,7 @@ impl Solution {
### C#
> 递归法:
```C#
```csharp
public TreeNode DeleteNode(TreeNode root, int key) {
// 第一种情况:没找到删除的节点,遍历到空节点直接返回了
if (root == null) return null;

View File

@ -332,6 +332,24 @@ object Solution {
}
}
```
### C#
```csharp
public class Solution
{
public int FindMinArrowShots(int[][] points)
{
if (points.Length == 0) return 0;
Array.Sort(points, (a, b) => a[0].CompareTo(b[0]));
int count = 1;
for (int i = 1; i < points.Length; i++)
{
if (points[i][0] > points[i - 1][1]) count++;
else points[i][1] = Math.Min(points[i][1], points[i - 1][1]);
}
return count;
}
}
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">

View File

@ -412,6 +412,75 @@ public int FourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
return res;
}
```
### C
```c
// 哈希表大小
const int HASH_SIZE = 101;
typedef struct node {
int val;
int count;
struct node *next;
} node, *HashMap;
// 哈希表插入
void hash_insert(HashMap hashmap[], int val) {
int idx = val < 0 ? (-val) % HASH_SIZE : val % HASH_SIZE, count = 0;
node *p = hashmap[idx];
while (p->next != NULL) {
p = p->next;
if (p->val == val) {
(p->count)++;
return;
}
}
node *new = malloc(sizeof(node));
new->val = val;
new->count = 1;
new->next = NULL;
p->next = new;
return;
}
// 哈希表查找
int hash_search(HashMap hashmap[], int val) {
int idx = val < 0 ? (-val) % HASH_SIZE : val % HASH_SIZE;
node *p = hashmap[idx];
while (p->next != NULL) {
p = p->next;
if (p->val == val) return p->count;
}
return 0;
}
int fourSumCount(int* nums1, int nums1Size, int* nums2, int nums2Size, int* nums3, int nums3Size, int* nums4, int nums4Size){
// 初始化哈希表
HashMap hashmap[HASH_SIZE];
for (int i = 0; i < HASH_SIZE; i++) {
hashmap[i] = malloc(sizeof(node));
hashmap[i]->next = NULL;
}
// 统计两个数组元素之和的负值和出现的次数,放到哈希表中
int count = 0, num;
for (int i = 0; i < nums1Size; i++) {
for(int j = 0; j < nums2Size; j++) {
num = - nums1[i] - nums2[j];
hash_insert(hashmap, num);
}
}
// 统计另外两个数组元素之和,查找哈希表中对应元素的出现次数,加入总次数
for (int i = 0; i < nums3Size; i++) {
for(int j = 0; j < nums4Size; j++) {
num = nums3[i] + nums4[j];
count += hash_search(hashmap, num);
}
}
return count;
}
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>

View File

@ -229,7 +229,7 @@ func findContentChildren(g []int, s []int) int {
### Rust
```rust
pub fn find_content_children(mut children: Vec<i32>, mut cookie: Vec<i32>) -> i32 {
pub fn find_content_children(mut children: Vec<i32>, mut cookies: Vec<i32>) -> i32 {
children.sort();
cookies.sort();

View File

@ -682,7 +682,7 @@ impl Solution {
}
```
### C#
```C#
```csharp
// 前缀表不减一
public bool RepeatedSubstringPattern(string s)
{

View File

@ -533,6 +533,67 @@ impl Solution {
}
}
```
## C
```c
#define max(a, b) ((a) > (b) ? (a) : (b))
int findMaxForm(char** strs, int strsSize, int m, int n) {
int dp[m + 1][n + 1];
memset(dp, 0, sizeof (int ) * (m + 1) * (n + 1));
for(int i = 0; i < strsSize; i++){
// 统计0和1的数量
int count0 = 0;
int count1 = 0;
char *str = strs[i];
while (*str != '\0'){
if(*str == '0'){
count0++;
} else{
count1++;
}
str++;
}
for(int j = m; j >= count0; j--){
for(int k = n; k >= count1; k--){
dp[j][k] = max(dp[j][k], dp[j - count0][k - count1] + 1);
}
}
}
return dp[m][n];
}
```
### C#
```csharp
public class Solution
{
public int FindMaxForm(string[] strs, int m, int n)
{
int[,] dp = new int[m + 1, n + 1];
foreach (string str in strs)
{
int zero = 0, one = 0;
foreach (char c in str)
{
if (c == '0') zero++;
else one++;
}
for (int i = m; i >= zero; i--)
{
for (int j = n; j >= one; j--)
{
dp[i, j] = Math.Max(dp[i, j], dp[i - zero, j - one] + 1);
}
}
}
return dp[m, n];
}
}
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">

View File

@ -585,6 +585,70 @@ impl Solution {
}
}
```
## C
```c
int getSum(int * nums, int numsSize){
int sum = 0;
for(int i = 0; i < numsSize; i++){
sum += nums[i];
}
return sum;
}
int findTargetSumWays(int* nums, int numsSize, int target) {
int sum = getSum(nums, numsSize);
int diff = sum - target;
// 两种情况不满足
if(diff < 0 || diff % 2 != 0){
return 0;
}
int bagSize = diff / 2;
int dp[numsSize + 1][bagSize + 1];
dp[0][0] = 1;
for(int i = 1; i <= numsSize; i++){
int num = nums[i - 1];
for(int j = 0; j <= bagSize; j++){
dp[i][j] = dp[i - 1][j];
if(j >= num){
dp[i][j] += dp[i - 1][j - num];
}
}
}
return dp[numsSize][bagSize];
}
```
### C#
```csharp
public class Solution
{
public int FindTargetSumWays(int[] nums, int target)
{
int sum = 0;
foreach (int num in nums)
{
sum += num;
}
if (Math.Abs(target) > sum) return 0;
if ((sum + target) % 2 == 1) return 0;
int bagSize = (sum + target) / 2;
int[] dp = new int[bagSize + 1];
dp[0] = 1;
for (int i = 0; i < nums.Length; i++)
{
for (int j = bagSize; j >= nums[i]; j--)
{
dp[j] += dp[j - nums[i]];
}
}
return dp[bagSize];
}
}
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">

View File

@ -256,6 +256,7 @@ class Solution {
### Python3
```python
# 版本一
class Solution:
def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
result = [-1]*len(nums1)
@ -273,6 +274,26 @@ class Solution:
stack.pop()
stack.append(i)
return result
# 版本二
class Solution:
def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
stack = []
# 创建答案数组
ans = [-1] * len(nums1)
for i in range(len(nums2)):
while len(stack) > 0 and nums2[i] > nums2[stack[-1]]:
# 判断 num1 是否有 nums2[stack[-1]]。如果没有这个判断会出现指针异常
if nums2[stack[-1]] in nums1:
# 锁定 num1 检索的 index
index = nums1.index(nums2[stack[-1]])
# 更新答案数组
ans[index] = nums2[i]
# 弹出小元素
# 这个代码一定要放在 if 外面。否则单调栈的逻辑就不成立了
stack.pop()
stack.append(i)
return ans
```
### Go

View File

@ -1010,7 +1010,7 @@ pub fn find_mode(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
}
```
### C#
```C#
```csharp
// 递归
public class Solution
{

View File

@ -170,7 +170,6 @@ class Solution {
### Python:
```python
# 方法 1:
class Solution:
def nextGreaterElements(self, nums: List[int]) -> List[int]:
dp = [-1] * len(nums)
@ -181,26 +180,6 @@ class Solution:
stack.pop()
stack.append(i%len(nums))
return dp
# 方法 2:
class Solution:
def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
stack = []
# 创建答案数组
ans = [-1] * len(nums1)
for i in range(len(nums2)):
while len(stack) > 0 and nums2[i] > nums2[stack[-1]]:
# 判断 num1 是否有 nums2[stack[-1]]。如果没有这个判断会出现指针异常
if nums2[stack[-1]] in nums1:
# 锁定 num1 检索的 index
index = nums1.index(nums2[stack[-1]])
# 更新答案数组
ans[index] = nums2[i]
# 弹出小元素
# 这个代码一定要放在 if 外面。否则单调栈的逻辑就不成立了
stack.pop()
stack.append(i)
return ans
```
### Go:

View File

@ -439,7 +439,7 @@ object Solution {
动态规划:
```c#
```csharp
public class Solution
{
public int Fib(int n)
@ -459,7 +459,7 @@ public class Solution
递归:
```c#
```csharp
public class Solution
{
public int Fib(int n)

View File

@ -685,7 +685,7 @@ impl Solution {
}
```
### C#
```C#
```csharp
//递归
int maxDepth = -1;
int res = 0;
@ -716,9 +716,55 @@ public void Traversal(TreeNode root, int depth)
return;
}
```
```csharp
/*
* @lc app=leetcode id=513 lang=csharp
* 迭代法
* [513] Find Bottom Left Tree Value
*/
// @lc code=start
public class Solution
{
public int FindBottomLeftValue(TreeNode root)
{
Queue<TreeNode> que = new Queue<TreeNode>();
if (root != null)
{
que.Enqueue(root);
}
int ans = 0;
while (que.Count != 0)
{
int size = que.Count;
for (var i = 0; i < size; i++)
{
var curNode = que.Peek();
que.Dequeue();
if(i == 0){
ans = curNode.val;
}
if (curNode.left != null)
{
que.Enqueue(curNode.left);
}
if (curNode.right != null)
{
que.Enqueue(curNode.right);
}
}
}
return ans;
}
}
// @lc code=end
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -224,20 +224,26 @@ class Solution {
// 二维dp数组版本方便理解
class Solution {
public int change(int amount, int[] coins) {
int[][] dp = new int[coins.length][amount + 1];
// 只有一种硬币的情况
for (int i = 0; i <= amount; i += coins[0]) {
dp[0][i] = 1;
int[][] dp = new int[coins.length][amount+1];
// 初始化边界值
for(int i = 0; i < coins.length; i++){
// 第一列的初始值为1
dp[i][0] = 1;
}
for (int i = 1; i < coins.length; i++) {
for (int j = 0; j <= amount; j++) {
// 第i种硬币使用0~k次求和
for (int k = 0; k * coins[i] <= j; k++) {
dp[i][j] += dp[i - 1][j - k * coins[i]];
}
for(int j = coins[0]; j <= amount; j++){
// 初始化第一行
dp[0][j] += dp[0][j-coins[0]];
}
for(int i = 1; i < coins.length; i++){
for(int j = 1; j <= amount; j++){
if(j < coins[i]) dp[i][j] = dp[i-1][j];
else dp[i][j] = dp[i][j-coins[i]] + dp[i-1][j];
}
}
return dp[coins.length - 1][amount];
return dp[coins.length-1][amount];
}
}
```
@ -347,8 +353,50 @@ object Solution {
}
}
```
## C
```c
int change(int amount, int* coins, int coinsSize) {
int dp[amount + 1];
memset(dp, 0, sizeof (dp));
dp[0] = 1;
// 遍历物品
for(int i = 0; i < coinsSize; i++){
// 遍历背包
for(int j = coins[i]; j <= amount; j++){
dp[j] += dp[j - coins[i]];
}
}
return dp[amount];
}
```
### C#
```csharp
public class Solution
{
public int Change(int amount, int[] coins)
{
int[] dp = new int[amount + 1];
dp[0] = 1;
for (int i = 0; i < coins.Length; i++)
{
for (int j = coins[i]; j <= amount; j++)
{
if (j >= coins[i])
dp[j] += dp[j - coins[i]];
}
}
return dp[amount];
}
}
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -648,7 +648,7 @@ impl Solution {
}
```
### C#
```C#
```csharp
// 递归
public class Solution
{

View File

@ -530,7 +530,7 @@ impl Solution {
}
```
### C#
```C#
```csharp
// 递归
public class Solution
{

View File

@ -789,7 +789,7 @@ impl Solution {
}
```
### C#
```C#
```csharp
public TreeNode MergeTrees(TreeNode root1, TreeNode root2)
{
if (root1 == null) return root2;

View File

@ -397,6 +397,7 @@ class Solution:
```
### Go
> 动态规划:
```Go
func countSubstrings(s string) int {
@ -422,6 +423,47 @@ func countSubstrings(s string) int {
return res
}
```
> 动态规划:简洁版
```Go
func countSubstrings(s string) int {
res := 0
dp := make([][]bool, len(s))
for i := 0; i < len(s); i++ {
dp[i] = make([]bool, len(s))
}
for i := len(s) - 1; i >= 0; i-- {
for j := i; j < len(s); j++ {
if s[i] == s[j] && (j-i <= 1 || dp[i+1][j-1]) {
res++
dp[i][j] = true
}
}
}
return res
}
```
> 双指针法:
```Go
func countSubstrings(s string) int {
extend := func(i, j int) int {
res := 0
for i >= 0 && j < len(s) && s[i] == s[j] {
i --
j ++
res ++
}
return res
}
res := 0
for i := 0; i < len(s); i++ {
res += extend(i, i) // 以i为中心
res += extend(i, i+1) // 以i和i+1为中心
}
return res
}
```
### Javascript

View File

@ -583,7 +583,7 @@ impl Solution {
}
```
### C#
```C#
```csharp
public TreeNode ConstructMaximumBinaryTree(int[] nums)
{
if (nums.Length == 0) return null;

View File

@ -79,7 +79,7 @@ public:
代码如下:
```
```cpp
TreeNode* trimBST(TreeNode* root, int low, int high)
```
@ -87,7 +87,7 @@ TreeNode* trimBST(TreeNode* root, int low, int high)
修剪的操作并不是在终止条件上进行的,所以就是遇到空节点返回就可以了。
```
```cpp
if (root == nullptr ) return nullptr;
```
@ -97,7 +97,7 @@ if (root == nullptr ) return nullptr;
代码如下:
```
```cpp
if (root->val < low) {
TreeNode* right = trimBST(root->right, low, high); // 寻找符合区间[low, high]的节点
return right;
@ -108,7 +108,7 @@ if (root->val < low) {
代码如下:
```
```cpp
if (root->val > high) {
TreeNode* left = trimBST(root->left, low, high); // 寻找符合区间[low, high]的节点
return left;
@ -119,7 +119,7 @@ if (root->val > high) {
最后返回root节点代码如下
```
```cpp
root->left = trimBST(root->left, low, high); // root->left接入符合条件的左孩子
root->right = trimBST(root->right, low, high); // root->right接入符合条件的右孩子
return root;
@ -133,7 +133,7 @@ return root;
如下代码相当于把节点0的右孩子节点2返回给上一层
```
```cpp
if (root->val < low) {
TreeNode* right = trimBST(root->right, low, high); // 寻找符合区间[low, high]的节点
return right;
@ -142,7 +142,7 @@ if (root->val < low) {
然后如下代码相当于用节点3的左孩子 把下一层返回的 节点0的右孩子节点2 接住。
```
``` cpp
root->left = trimBST(root->left, low, high);
```
@ -568,7 +568,7 @@ impl Solution {
}
```
### C#
```C#
```csharp
// 递归
public TreeNode TrimBST(TreeNode root, int low, int high)
{

View File

@ -425,6 +425,57 @@ function findLengthOfLCIS(nums: number[]): number {
};
```
### C
> 动态规划:
```c
int findLengthOfLCIS(int* nums, int numsSize) {
if(numsSize == 0){
return 0;
}
int dp[numsSize];
for(int i = 0; i < numsSize; i++){
dp[i] = 1;
}
int result = 1;
for (int i = 1; i < numsSize; ++i) {
if(nums[i] > nums[i - 1]){
dp[i] = dp[i - 1] + 1;
}
if(dp[i] > result){
result = dp[i];
}
}
return result;
}
```
> 贪心:
```c
int findLengthOfLCIS(int* nums, int numsSize) {
int result = 1;
int count = 1;
if(numsSize == 0){
return result;
}
for (int i = 1; i < numsSize; ++i) {
if(nums[i] > nums[i - 1]){
count++;
} else{
count = 1;
}
if(count > result){
result = count;
}
}
return result;
}
```
@ -432,4 +483,3 @@ function findLengthOfLCIS(nums: number[]): number {
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -69,7 +69,7 @@ edges[2][0] = 2edges[2][1] = 3
搞清楚之后,我们如何统计入度呢?
即 edges[i][1] 表示的节点都是 箭头指向的节点,即这个点有一个入度! (如果想统计出度,那么就是 edges[i][0])。
即 edges[i][1] 表示的节点都是 箭头指向的节点,即这个点有一个入度! (如果想统计出度,那么就是 edges[i][0])。
所以,统计入度的代码如下:
@ -81,7 +81,7 @@ for (int i = 0; i < n; i++) {
}
```
前两种入度为2的情况一定是删除指向入度为2的节点的两条边其中的一条如果删了一条判断这个图是一个树那么这条边就是答案同时注意要从后向前遍历因为如果两边删哪一条都可以成为树,就删最后那一条。
前两种入度为2的情况一定是删除指向入度为2的节点的两条边其中的一条如果删了一条判断这个图是一个树那么这条边就是答案同时注意要从后向前遍历因为如果两边删哪一条都可以成为树,就删最后那一条。
代码如下:
@ -108,7 +108,7 @@ if (vec.size() > 0) {
可以定义一个函数,代码如下:
```
```cpp
// 在有向图里找到删除的那条边,使其变成树,返回值就是要删除的边
vector<int> getRemoveEdge(const vector<vector<int>>& edges)
```

View File

@ -428,6 +428,146 @@ var maxAreaOfIsland = function (grid) {
};
```
### Go
dsf: 版本一
```go
var DIRECTIONS = [4][2]int{{-1, 0}, {0, -1}, {1, 0}, {0, 1}}
var count int = 0
func maxAreaOfIsland(grid [][]int) int {
res := 0
visited := make([][]bool, len(grid))
for i := 0; i < len(grid); i++ {
visited[i] = make([]bool, len(grid[0]))
}
for i, rows := range grid {
for j, v := range rows {
if v == 1 && !visited[i][j] {
// 第一种写法,重制 count必定有 1 个
count = 1
dfs(grid, visited, i, j)
res = max(res, count)
}
}
}
return res
}
// 第一种写法
func dfs(grid [][]int, visited [][]bool, i, j int) {
visited[i][j] = true // 标记已访问,循环中未标记会导致重复
for _, d := range DIRECTIONS {
x, y := i+d[0], j+d[1]
if x < 0 || x >= len(grid) || y < 0 || y >= len(grid[0]) {
continue
}
if grid[x][y] == 1 && !visited[x][y] {
count++
dfs(grid, visited, x, y)
}
}
}
```
dfs版本二
```go
var DIRECTIONS = [4][2]int{{-1, 0}, {0, -1}, {1, 0}, {0, 1}}
var count int = 0
func maxAreaOfIsland(grid [][]int) int {
res := 0
visited := make([][]bool, len(grid))
for i := 0; i < len(grid); i++ {
visited[i] = make([]bool, len(grid[0]))
}
for i, rows := range grid {
for j, v := range rows {
if v == 1 && !visited[i][j] {
// 第二种写法
count = 0
dfs(grid, visited, i, j)
res = max(res, count)
}
}
}
return res
}
// 第二种写法
func dfs(grid [][]int, visited [][]bool, i, j int) {
if visited[i][j] || grid[i][j] == 0 {
return
}
visited[i][j] = true
count++
for _, d := range DIRECTIONS {
x, y := i+d[0], j+d[1]
if x < 0 || x >= len(grid) || y < 0 || y >= len(grid[0]) {
continue
}
dfs(grid, visited, x, y)
}
}
```
bfs:
```go
var DIRECTIONS = [4][2]int{{-1, 0}, {0, -1}, {1, 0}, {0, 1}}
var count int = 0
func maxAreaOfIsland(grid [][]int) int {
res := 0
visited := make([][]bool, len(grid))
for i := 0; i < len(grid); i++ {
visited[i] = make([]bool, len(grid[0]))
}
for i, rows := range grid {
for j, v := range rows {
if v == 1 && !visited[i][j] {
count = 0
bfs(grid, visited, i, j)
res = max(res, count)
}
}
}
return res
}
// bfs
func bfs(grid [][]int, visited [][]bool, i, j int) {
visited[i][j] = true
count++
queue := [][2]int{{i, j}}
for len(queue) > 0 {
cur := queue[0]
queue = queue[1:]
for _, d := range DIRECTIONS {
x, y := cur[0]+d[0], cur[1]+d[1]
if x < 0 || x >= len(grid) || y < 0 || y >= len(grid[0]) {
continue
}
if grid[x][y] == 1 && !visited[x][y] {
count++
queue = append(queue, [2]int{x, y})
visited[x][y] = true
}
}
}
}
```
### Rust

View File

@ -465,7 +465,7 @@ impl Solution {
}
```
### C#
```C#
```csharp
// 递归
public TreeNode SearchBST(TreeNode root, int val)
{

View File

@ -59,7 +59,7 @@
代码如下:
```
```cpp
TreeNode* insertIntoBST(TreeNode* root, int val)
```
@ -69,7 +69,7 @@ TreeNode* insertIntoBST(TreeNode* root, int val)
代码如下:
```
```cpp
if (root == NULL) {
TreeNode* node = new TreeNode(val);
return node;
@ -88,7 +88,7 @@ if (root == NULL) {
代码如下:
```
```cpp
if (root->val > val) root->left = insertIntoBST(root->left, val);
if (root->val < val) root->right = insertIntoBST(root->right, val);
return root;
@ -120,7 +120,7 @@ public:
那么递归函数定义如下:
```
```cpp
TreeNode* parent; // 记录遍历节点的父节点
void traversal(TreeNode* cur, int val)
```

View File

@ -1486,7 +1486,7 @@ impl MyLinkedList {
```
### C#
```C#
```csharp
class ListNode
{
public int val;

View File

@ -247,7 +247,29 @@ function maxProfit(prices: number[], fee: number): number {
};
```
### C:
```c
#define max(a, b) ((a) > (b) ? (a) : (b))
// dp[i][0] 表示第i天持有股票所省最多现金。
// dp[i][1] 表示第i天不持有股票所得最多现金
int maxProfit(int* prices, int pricesSize, int fee) {
int dp[pricesSize][2];
dp[0][0] = -prices[0];
dp[0][1] = 0;
for (int i = 1; i < pricesSize; ++i) {
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]);
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i] - fee);
}
return dp[pricesSize - 1][1];
}
```
### Rust:
**贪心**
```Rust
@ -304,3 +326,4 @@ impl Solution {
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -560,10 +560,30 @@ impl Solution {
}
```
### C:
```c
int findLength(int* nums1, int nums1Size, int* nums2, int nums2Size) {
int dp[nums1Size + 1][nums2Size + 1];
memset(dp, 0, sizeof(dp));
int result = 0;
for (int i = 1; i <= nums1Size; ++i) {
for (int j = 1; j <= nums2Size; ++j) {
if(nums1[i - 1] == nums2[j - 1]){
dp[i][j] = dp[i - 1][j - 1] + 1;
}
if(dp[i][j] > result){
result = dp[i][j];
}
}
}
return result;
}
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -392,9 +392,58 @@ impl Solution {
}
}
```
### C
```c
int monotoneIncreasingDigits(int n) {
char str[11];
// 将数字转换为字符串
sprintf(str, "%d", n);
int len = strlen(str);
int flag = strlen(str);
for(int i = len - 1; i > 0; i--){
if(str[i] < str[i - 1]){
str[i - 1]--;
flag = i;
}
}
for(int i = flag; i < len; i++){
str[i] = '9';
}
// 字符串转数字
return atoi(str);
}
```
### C#
```csharp
public class Solution
{
public int MonotoneIncreasingDigits(int n)
{
char[] s = n.ToString().ToCharArray();
int flag = s.Length;
for (int i = s.Length - 1; i > 0; i--)
{
if (s[i - 1] > s[i])
{
flag = i;
s[i - 1]--;
}
}
for (int i = flag; i < s.Length; i++)
{
s[i] = '9';
}
return int.Parse(new string(s));
}
}
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -500,7 +500,7 @@ object Solution {
### C#
```c#
```csharp
public class Solution
{
public int MinCostClimbingStairs(int[] cost)

View File

@ -404,9 +404,65 @@ impl Solution {
}
}
```
### C
```c
#define max(a, b) ((a) > (b) ? (a) : (b))
int* partitionLabels(char* s, int* returnSize) {
// 记录每个字符最远出现的位置
int last[26] = {0};
int len = strlen(s);
for (int i = 0; i < len; ++i) {
last[s[i] - 'a'] = i;
}
int left = 0, right = 0;
int * partition = malloc(sizeof (int ) * len);
// 初始化值
*returnSize = 0;
for(int i = 0; i < len; i++){
right = max(right, last[s[i] - 'a']);
// 到达最远位置,加入答案,并且更新左边下标
if(i == right){
partition[(*returnSize)++] = right - left + 1;
left = i + 1;
}
}
return partition;
}
```
### C#
```csharp
public class Solution
{
public IList<int> PartitionLabels(string s)
{
int[] location = new int[27];
for (int i = 0; i < s.Length; i++)
{
location[s[i] - 'a'] = i;
}
List<int> res = new List<int>();
int left = 0, right = 0;
for (int i = 0; i < s.Length; i++)
{
right = Math.Max(right, location[s[i] - 'a']);
if (i == right)
{
res.Add(right - left + 1);
left = i + 1;
}
}
return res;
}
}
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -348,6 +348,162 @@ class Solution:
```
### Go
```go
func largestIsland(grid [][]int) int {
dir := [][]int{{0, 1}, {1, 0}, {-1, 0}, {0, -1}}
n := len(grid)
m := len(grid[0])
area := 0
visited := make([][]bool, n)
for i := 0; i < n; i++ {
visited[i] = make([]bool, m)
}
gridNum := make(map[int]int, 0) // 记录每一个岛屿的面积
mark := 2 // 记录每个岛屿的编号
isAllGrid := true
res := 0 // 标记是否整个地图都是陆地
var dfs func(grid [][]int, visited [][]bool, x, y, mark int)
dfs = func(grid [][]int, visited [][]bool, x, y, mark int) {
// 终止条件:访问过的节点 或者 遇到海水
if visited[x][y] || grid[x][y] == 0 {
return
}
visited[x][y] = true // 标记访问过
grid[x][y] = mark // 给陆地标记新标签
area++
for i := 0; i < 4; i++ {
nextX := x + dir[i][0]
nextY := y + dir[i][1]
if nextX < 0 || nextX >= len(grid) || nextY < 0 || nextY >= len(grid[0]) {
continue
}
dfs(grid, visited, nextX, nextY, mark)
}
}
for i := 0; i < n; i++ {
for j := 0; j < m; j++ {
if grid[i][j] == 0 {
isAllGrid = false
}
if !visited[i][j] && grid[i][j] == 1 {
area = 0
dfs(grid, visited, i, j, mark) // 将与其链接的陆地都标记上 true
gridNum[mark] = area // 记录每一个岛屿的面积
mark++ // 更新下一个岛屿编号
}
}
}
if isAllGrid {
return n * m
}
// 根据添加陆地的位置,计算周边岛屿面积之和
visitedGrid := make(map[int]struct{}) // 标记访问过的岛屿
for i := 0; i < n; i++ {
for j := 0; j < m; j++ {
count := 1 // 记录连接之后的岛屿数量
visitedGrid = make(map[int]struct{}) // 每次使用时,清空
if grid[i][j] == 0 {
for k := 0; k < 4; k++ {
// 计算相邻坐标
nearI := i + dir[k][0]
nearJ := j + dir[k][1]
if nearI < 0 || nearI >= len(grid) || nearJ < 0 || nearJ >= len(grid[0]) {
continue
}
// 添加过的岛屿不要重复添加
if _, ok := visitedGrid[grid[nearI][nearJ]]; ok {
continue
}
// 把相邻四面的岛屿数量加起来
count += gridNum[grid[nearI][nearJ]]
// 标记该岛屿已经添加过
visitedGrid[grid[nearI][nearJ]] = struct{}{}
}
}
res = max827(res, count)
}
}
return res
}
func max827(x, y int) int {
if x > y {
return x
}
return y
}
```
### JavaScript
```JavaScript
var largestIsland = function(grid) {
let res = 0;
const m = grid.length;
const n = grid[0].length;
const tag = new Array(n).fill().map(_ => new Array(m).fill(0));
const area = new Map();
const dir = [[0,1],[0,-1],[1,0],[-1,0]];
const dfs = (grid,tag,x,y,mark) => {
let res = 1;
tag[x][y] = mark;
for(let i = 0; i < dir.length; i++) {
let nextX = x + dir[i][0];
let nextY = y + dir[i][1];
if(nextX < 0 || nextX >= m || nextY < 0 || nextY >= n) {
continue;
}
if(grid[nextX][nextY] === 1 && tag[nextX][nextY] === 0) {
res += dfs(grid,tag,nextX,nextY,mark);
}
}
return res;
}
let mark = 2;
//将岛屿用mark标记
for(let i = 0; i < m; i++) {
for(let j = 0; j < n; j++) {
if(grid[i][j] === 1 && tag[i][j] === 0) {
area.set(mark,dfs(grid,tag,i,j,mark));
res = Math.max(res,area.get(mark));
mark++;
}
}
}
//将一个非岛屿格子变为岛屿
for(let i = 0; i < m; i++) {
for(let j = 0; j < n; j++) {
if(grid[i][j] === 0) {
let z = 1;
const connected = new Set();
for(let k = 0; k < dir.length; k++) {
let nextX = i + dir[k][0];
let nextY = j + dir[k][1];
if(nextX < 0 || nextX >= m || nextY < 0 || nextY >= n || tag[nextX][nextY] === 0 || connected.has(tag[nextX][nextY])) {
continue;
}
z += area.get(tag[nextX][nextY]);
connected.add(tag[nextX][nextY]);
}
res = Math.max(res,z);
}
}
}
return res;
};
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>

View File

@ -369,8 +369,44 @@ class Solution {
}
```
简化分支版本:
```java
class Solution {
static int ans;
public int minCameraCover(TreeNode root) {
ans = 0; // 初始化
if(f(root) == 0) ans ++;
return ans;
}
// 定义 f 函数有三种返回值情况
// 0表示 x 节点没有被相机监控,只能依靠父节点放相机
// 1表示 x 节点被相机监控,但相机不是放在自身节点上
// 2表示 x 节点被相机监控,但相机放在自身节点上
public static int f(TreeNode x) {
if(x == null) return 1; // 空树认为被监控,但没有相机
// 左右递归到最深处
int l = f(x.left);
int r = f(x.right);
// 有任意一个子节点为空,就需要当前节点放相机,不然以后没机会
if(l == 0 || r == 0) {
ans ++; // 放相机
return 2;
}
// 贪心策略,左右子树都被监控,且没有监控到当前节点,
// 那么最有利的情况就是将相机放置在当前节点父节点上,
// 因为这样能多监控可能的子树节点和父父节点
if(l == 1 && r == 1) return 0;
// 剩下情况就是左右子树有可能为 2即当前节点被监控
return 1;
}
}
```
### Python
贪心(版本一)
```python
class Solution:
@ -726,10 +762,34 @@ impl Solution {
}
}
```
### C#
```csharp
public class Solution
{
public int res = 0;
public int MinCameraCover(TreeNode root)
{
if (Traversal(root) == 0) res++;
return res;
}
public int Traversal(TreeNode cur)
{
if (cur == null) return 2;
int left = Traversal(cur.left);
int right = Traversal(cur.right);
if (left == 2 && right == 2) return 0;
else if (left == 0 || right == 0)
{
res++;
return 1;
}
else return 2;
}
}
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -327,37 +327,45 @@ var commonChars = function(words) {
### GO
```golang
func commonChars(words []string) []string {
length:=len(words)
fre:=make([][]int,0)//统计每个字符串的词频
res:=make([]string,0)
//统计词频
for i:=0;i<length;i++{
var row [26]int//存放该字符串的词频
for j:=0;j<len(words[i]);j++{
row[words[i][j]-97]++
}
fre=append(fre,row[:])
}
//查找一列的最小值
for j:=0;j<len(fre[0]);j++{
pre:=fre[0][j]
for i:=0;i<len(fre);i++{
pre=min(pre,fre[i][j])
}
//将该字符添加到结果集(按照次数)
tmpString:=string(j+97)
for i:=0;i<pre;i++{
res=append(res,tmpString)
}
}
return res
func commonChars(A []string) []string {
var result []string
if len(A) == 0 {
return result
}
hash := make([]int, 26) // 用来统计所有字符串里字符出现的最小频率
for _, c := range A[0] { // 用第一个字符串给hash初始化
hash[c-'a']++
}
for i := 1; i < len(A); i++ {
hashOtherStr := make([]int, 26) // 统计除第一个字符串外字符的出现频率
for _, c := range A[i] {
hashOtherStr[c-'a']++
}
// 更新hash保证hash里统计26个字符在所有字符串里出现的最小次数
for k := 0; k < 26; k++ {
hash[k] = min(hash[k], hashOtherStr[k])
}
}
// 将hash统计的字符次数转成输出形式
for i := 0; i < 26; i++ {
for hash[i] > 0 {
s := string('a' + i) // rune -> string
result = append(result, s)
hash[i]--
}
}
return result
}
func min(a,b int)int{
if a>b{
return b
}
return a
func min(a, b int) int {
if a < b {
return a
}
return b
}
```

View File

@ -491,6 +491,120 @@ class Solution:
return ans
```
### Go
dfs:
```go
var DIRECTIONS = [4][2]int{{-1, 0}, {0, -1}, {1, 0}, {0, 1}}
var count int = 0
func numEnclaves(grid [][]int) int {
rows, cols := len(grid), len(grid[0])
// 行
for i := range grid[0] {
if grid[0][i] == 1 {
dfs(grid, 0, i)
}
if grid[rows-1][i] == 1 {
dfs(grid, rows-1, i)
}
}
// 列
for j := range grid {
if grid[j][0] == 1 {
dfs(grid, j, 0)
}
if grid[j][cols-1] == 1 {
dfs(grid, j, cols-1)
}
}
count = 0
for i := range grid {
for j := range grid[0] {
if grid[i][j] == 1 {
dfs(grid, i, j)
}
}
}
return count
}
func dfs(grid [][]int, i, j int) {
grid[i][j] = 0
count++
for _, d := range DIRECTIONS {
x, y := i+d[0], j+d[1]
if x < 0 || x >= len(grid) || y < 0 || y >= len(grid[0]) {
continue
}
if grid[x][y] == 1 {
dfs(grid, x, y)
}
}
}
```
bfs:
```go
var DIRECTIONS = [4][2]int{{-1, 0}, {0, -1}, {1, 0}, {0, 1}}
var count int = 0
func numEnclaves(grid [][]int) int {
rows, cols := len(grid), len(grid[0])
// 行
for i := range grid[0] {
if grid[0][i] == 1 {
bfs(grid, 0, i)
}
if grid[rows-1][i] == 1 {
bfs(grid, rows-1, i)
}
}
// 列
for j := range grid {
if grid[j][0] == 1 {
bfs(grid, j, 0)
}
if grid[j][cols-1] == 1 {
bfs(grid, j, cols-1)
}
}
count = 0
for i := range grid {
for j := range grid[0] {
if grid[i][j] == 1 {
bfs(grid, i, j)
}
}
}
return count
}
func bfs(grid [][]int, i, j int) {
queue := [][]int{}
queue = append(queue, []int{i, j})
grid[i][j] = 0
count++
for len(queue) > 0 {
cur := queue[0]
queue = queue[1:]
for _, d := range DIRECTIONS {
x, y := cur[0]+d[0], cur[1]+d[1]
if x < 0 || x >= len(grid) || y < 0 || y >= len(grid[0]) {
continue
}
if grid[x][y] == 1 {
count++
queue = append(queue, []int{x, y})
grid[x][y] = 0
}
}
}
}
```
### Rust
dfs:

View File

@ -472,6 +472,30 @@ impl Solution {
}
}
```
### C#
```csharp
public class Solution
{
public int LastStoneWeightII(int[] stones)
{
int[] dp = new int[15001];
int sum = 0;
foreach (int stone in stones)
{
sum += stone;
}
int target = sum / 2;
for (int i = 0; i < stones.Length; i++)
{
for (int j = target; j >= stones[i]; j--)
{
dp[j] = Math.Max(dp[j], dp[j - stones[i]] + stones[i]);
}
}
return sum - 2 * dp[target];
}
}
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">

View File

@ -376,10 +376,32 @@ impl Solution {
}
```
### C:
```c
#define max(a, b) ((a) > (b) ? (a) : (b))
int longestCommonSubsequence(char* text1, char* text2) {
int text1Len = strlen(text1);
int text2Len = strlen(text2);
int dp[text1Len + 1][text2Len + 1];
memset(dp, 0, sizeof (dp));
for (int i = 1; i <= text1Len; ++i) {
for (int j = 1; j <= text2Len; ++j) {
if(text1[i - 1] == text2[j - 1]){
dp[i][j] = dp[i - 1][j - 1] + 1;
} else{
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
return dp[text1Len][text2Len];
}
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -4,30 +4,28 @@
</a>
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
# 1971. 寻找图中是否存在路径
# 1971. 寻找图中是否存在路径
[题目链接](https://leetcode.cn/problems/find-if-path-exists-in-graph/)
有一个具有 n个顶点的 双向 图,其中每个顶点标记从 0 到 n - 1包含 0 和 n - 1。图中的边用一个二维整数数组 edges 表示,其中 edges[i] = [ui, vi] 表示顶点 ui 和顶点 vi 之间的双向边。 每个顶点对由 最多一条 边连接,并且没有顶点存在与自身相连的边。
有一个具有 n 个顶点的 双向 图,其中每个顶点标记从 0 到 n - 1包含 0 和 n - 1。图中的边用一个二维整数数组 edges 表示,其中 edges[i] = [ui, vi] 表示顶点 ui 和顶点 vi 之间的双向边。 每个顶点对由 最多一条 边连接,并且没有顶点存在与自身相连的边。
请你确定是否存在从顶点 start 开始,到顶点 end 结束的 有效路径 。
给你数组 edges 和整数 n、start和end如果从 start 到 end 存在 有效路径 ,则返回 true否则返回 false 。
![](https://code-thinking-1253855093.file.myqcloud.com/pics/20220705101442.png)
给你数组 edges 和整数 n、start 和 end如果从 start 到 end 存在 有效路径 ,则返回 true否则返回 false 。
![](https://code-thinking-1253855093.file.myqcloud.com/pics/20220705101442.png)
提示:
* 1 <= n <= 2 * 10^5
* 0 <= edges.length <= 2 * 10^5
* edges[i].length == 2
* 0 <= ui, vi <= n - 1
* ui != vi
* 0 <= start, end <= n - 1
* 不存在双向边
* 不存在指向顶点自身的边
- 1 <= n <= 2 \* 10^5
- 0 <= edges.length <= 2 \* 10^5
- edges[i].length == 2
- 0 <= ui, vi <= n - 1
- ui != vi
- 0 <= start, end <= n - 1
- 不存在双向边
- 不存在指向顶点自身的边
## 思路
@ -70,7 +68,7 @@ void join(int u, int v) {
}
```
以上模板中,只要修改 n 大小就可以本题n不会超过2 * 10^5。
以上模板中,只要修改 n 大小就可以,本题 n 不会超过 2 \* 10^5。
并查集主要有三个功能。
@ -80,17 +78,17 @@ void join(int u, int v) {
简单介绍并查集之后,我们再来看一下这道题目。
为什么说这道题目是并查集基础题目,题目中各个点是双向图链接,那么判断 一个顶点到另一个顶点有没有有效路径其实就是看这两个顶点是否在同一个集合里。
为什么说这道题目是并查集基础题目,题目中各个点是双向图链接,那么判断 一个顶点到另一个顶点有没有有效路径其实就是看这两个顶点是否在同一个集合里。
如何算是同一个集合呢,有边连在一起,就算是一个集合。
如何算是同一个集合呢,有边连在一起,就算是一个集合。
此时我们就可以直接套用并查集模板。
此时我们就可以直接套用并查集模板。
使用join(int u, int v)将每条边加入到并查集。
使用 join(int u, int v)将每条边加入到并查集。
最后 isSame(int u, int v) 判断是否是同一个根 就可以了。
最后 isSame(int u, int v) 判断是否是同一个根 就可以了。
C++代码如下:
C++代码如下:
```CPP
class Solution {
@ -191,7 +189,7 @@ class Solution {
### Python
PYTHON并查集解法如下
PYTHON 并查集解法如下:
```PYTHON
class Solution:
@ -206,6 +204,85 @@ class Solution:
return find(source) == find(destination)
```
### Javascript
Javascript 并查集解法如下:
```Javascript
class unionF{
constructor(n){
this.count = n
this.roots = new Array(n).fill(0).map((item,index)=>index)
}
findRoot(x){
if(this.roots[x]!==x){
this.roots[x] = this.findRoot(this.roots[x])
}
return this.roots[x]
}
union(x,y){
const rx = this.findRoot(x)
const ry = this.findRoot(y)
this.roots[rx] = ry
this.count--
}
isConnected(x,y){
return this.findRoot(x)===this.findRoot(y)
}
}
var validPath = function(n, edges, source, destination) {
const UF = new unionF(n)
for(const [s,t] of edges){
UF.union(s,t)
}
return UF.isConnected(source,destination)
};
```
Javascript 双向 bfs 解法如下:
```Javascript
var validPath = function(n, edges, source, destination) {
const graph = new Array(n).fill(0).map(()=>[])
for(const [s,t] of edges){
graph[s].push(t)
graph[t].push(s)
}
const visited = new Array(n).fill(false)
function bfs(start,end,graph){
const startq = [start]
const endq = [end]
while(startq.length&&endq.length){
const slen = startq.length
for(let i = 0;i<slen;i++){
const scur = startq.shift()
if(visited[scur]) continue
if(endq.includes(scur)) return true
visited[scur] = true
const neighbors = graph[scur]
startq.push(...neighbors)
}
const elen = endq.length
for(let i = 0;i<elen;i++){
const ecur = endq.shift()
if(visited[ecur]) continue
if(startq.includes(ecur)) return true
visited[ecur] = true
const neighbors = graph[ecur]
endq.push(...neighbors)
}
}
return false
}
return bfs(source,destination,graph)
};
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">

View File

@ -56,36 +56,36 @@
C++代码如下:
```CPP
#include<iostream>
#include <iostream>
using namespace std;
int main() {
string s;
while (cin >> s) {
int sOldIndex = s.size() - 1;
int count = 0; // 统计数字的个数
int sOldSize = s.size();
for (int i = 0; i < s.size(); i++) {
if (s[i] >= '0' && s[i] <= '9') {
count++;
}
}
// 扩充字符串s的大小也就是每个空格替换成"number"之后的大小
// 扩充字符串s的大小也就是将每个数字替换成"number"之后的大小
s.resize(s.size() + count * 5);
int sNewSize = s.size();
// 从后先前将空格替换为"number"
for (int i = sNewSize - 1, j = sOldSize - 1; j < i; i--, j--) {
if (s[j] > '9' || s[j] < '0') {
s[i] = s[j];
int sNewIndex = s.size() - 1;
// 从后往前将数字替换为"number"
while (sOldIndex >= 0) {
if (s[sOldIndex] >= '0' && s[sOldIndex] <= '9') {
s[sNewIndex--] = 'r';
s[sNewIndex--] = 'e';
s[sNewIndex--] = 'b';
s[sNewIndex--] = 'm';
s[sNewIndex--] = 'u';
s[sNewIndex--] = 'n';
} else {
s[i] = 'r';
s[i - 1] = 'e';
s[i - 2] = 'b';
s[i - 3] = 'm';
s[i - 4] = 'u';
s[i - 5] = 'n';
i -= 5;
s[sNewIndex--] = s[sOldIndex];
}
sOldIndex--;
}
cout << s << endl;
cout << s << endl;
}
}
@ -245,7 +245,60 @@ class Solution:
return ''.join(lst)
```
### JavaScript:
```js
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
})
function main() {
const num0 = "0".charCodeAt();
const num9 = "9".charCodeAt();
const a = "a".charCodeAt();
const z = "z".charCodeAt();
function isAZ(str) {
return str >= a && str <= z;
}
function isNumber(str) {
return str >= num0 && str <= num9;
}
rl.on("line", (input) => {
let n = 0;
for (let i = 0; i < input.length; i++) {
const val = input[i].charCodeAt();
if (isNumber(val)) {
n+= 6;
}
if (isAZ(val)) {
n++;
}
}
const ans = new Array(n).fill(0);
let index = input.length - 1;
for (let i = n - 1; i >= 0; i--) {
const val = input[index].charCodeAt();
if (isAZ(val)) {
ans[i] = input[index];
}
if (isNumber(val)) {
ans[i] = "r";
ans[i - 1] = "e";
ans[i - 2] = "b";
ans[i - 3] = "m";
ans[i - 4] = "u";
ans[i - 5] = "n";
i -= 5;
}
index--;
}
console.log(ans.join(""));
})
}
main();
```
### TypeScript

Some files were not shown because too many files have changed in this diff Show More