Skip to content
Merged
42 changes: 42 additions & 0 deletions problems/0200.岛屿数量.深搜版.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,48 @@ public void dfs(char[][] grid, int i, int j){
dfs(grid,i,j + 1);
dfs(grid,i,j - 1);
}
```
```java
//graph - dfs (和卡哥的代碼邏輯一致)
class Solution {
boolean[][] visited;
int dir[][] = {
{0, 1}, //right
{1, 0}, //down
{-1, 0}, //up
{0, -1} //left
};
public int numIslands(char[][] grid) {
int count = 0;
visited = new boolean[grid.length][grid[0].length];

for(int i = 0; i < grid.length; i++){
for(int j = 0; j < grid[0].length; j++){
if(visited[i][j] == false && grid[i][j] == '1'){
count++;
dfs(grid, i, j);
}
}
}
return count;
}

private void dfs(char[][]grid, int x, int y){
if(visited[x][y] == true || grid[x][y] == '0')
return;

visited[x][y] = true;

for(int i = 0; i < 4; i++){
int nextX = x + dir[i][0];
int nextY = y + dir[i][1];
if(nextX < 0 || nextY < 0 || nextX >= grid.length || nextY >= grid[0].length)
continue;
dfs(grid, nextX, nextY);
}
}
}
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
Expand Down
1 change: 1 addition & 0 deletions problems/0242.有效的字母异位词.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ class Solution(object):
a_count = Counter(s)
b_count = Counter(t)
return a_count == b_count
```

Go:

Expand Down
79 changes: 79 additions & 0 deletions problems/0494.目标和.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,85 @@ class Solution {
}
```

易于理解的二维数组版本:
```java
class Solution {
public int findTargetSumWays(int[] nums, int target) {

// 01背包应用之“有多少种不同的填满背包最大容量的方法“
// 易于理解的二维数组解法及详细注释

int sum = 0;
for(int i = 0; i < nums.length; i++) {
sum += nums[i];
}

// 注意nums[i] >= 0的题目条件,意味着sum也是所有nums[i]的绝对值之和
// 这里保证了sum + target一定是大于等于零的,也就是left大于等于零(毕竟我们定义left大于right)
if(sum < Math.abs(target)){
return 0;
}

// 利用二元一次方程组将left用target和sum表示出来(替换掉right组合),详见代码随想录对此题的分析
// 如果所求的left数组和为小数,则作为整数数组的nums里的任何元素自然是没有办法凑出这个小数的
if((sum + target) % 2 != 0) {
return 0;
}

int left = (sum + target) / 2;

// dp[i][j]:遍历到数组第i个数时, left为j时的能装满背包的方法总数
int[][] dp = new int[nums.length][left + 1];

// 初始化最上行(dp[0][j]),当nums[0] == j时(注意nums[0]和j都一定是大于等于零的,因此不需要判断等于-j时的情况),有唯一一种取法可取到j,dp[0][j]此时等于1
// 其他情况dp[0][j] = 0
// java整数数组默认初始值为0
for(int j = 0; j <= left; j++) {
if(nums[0] == j) {
dp[0][j] = 1;
}
}

// 初始化最左列(dp[i][0])
// 当从nums数组的索引0到i的部分有n个0时(n > 0),每个0可以取+/-,因此有2的n次方中可以取到j = 0的方案
// n = 0说明当前遍历到的数组部分没有0全为正数,因此只有一种方案可以取到j = 0(就是所有数都不取)
int numZeros = 0;
for(int i = 0; i < nums.length; i++) {
if(nums[i] == 0) {
numZeros++;
}
dp[i][0] = (int) Math.pow(2, numZeros);

}

// 递推公式分析:
// 当nums[i] > j时,这时候nums[i]一定不能取,所以是dp[i - 1][j]种方案数
// nums[i] <= j时,num[i]可取可不取,因此方案数是dp[i - 1][j] + dp[i - 1][j - nums[i]]
// 由递推公式可知,先遍历i或j都可
for(int i = 1; i < nums.length; i++) {
for(int j = 1; j <= left; j++) {
if(nums[i] > j) {
dp[i][j] = dp[i - 1][j];
} else {
dp[i][j] = dp[i - 1][j] + dp[i - 1][j - nums[i]];
}
}
}

// 打印dp数组
// for(int i = 0; i < nums.length; i++) {
// for(int j = 0; j <= left; j++) {
// System.out.print(dp[i][j] + " ");
// }
// System.out.println("");
// }

return dp[nums.length - 1][left];

}
}
```

### Python
回溯版
```python
Expand Down
31 changes: 31 additions & 0 deletions problems/0647.回文子串.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,38 @@ class Solution {
}
}
```
LeetCode 5. Longest Palindromic Substring(LeetCode 647. 同一題的思路改一下、加一點,就能通過LeetCode 5)
```java
class Solution {
public String longestPalindrome(String s) {
//題目要求要return 最長的回文連續子串,故需要記錄當前最長的連續回文子串長度、最終起點、最終終點。
int finalStart = 0;
int finalEnd = 0;
int finalLen = 0;

char[] chars = s.toCharArray();
int len = chars.length;

boolean[][] dp = new boolean[len][len];
for (int i = len - 1; i >= 0; i--) {
for (int j = i; j < len; j++) {
if (chars[i] == chars[j] && (j - i <= 1 || dp[i + 1][j - 1]))
dp[i][j] = true;
//和LeetCode 647,差別就在這個if statement。
//如果當前[i, j]範圍內的substring是回文子串(dp[i][j]) 且(&&) 長度大於當前要記錄的最終長度(j - i + 1 > finalLen)
//我們就更新 當前最長的連續回文子串長度、最終起點、最終終點
if (dp[i][j] && j - i + 1 > finalLen) {
finalLen = j - i + 1;
finalStart = i;
finalEnd = j;
}
}
}
//String.substring這個method的用法是[起點, 終點),包含起點,不包含終點(左閉右開區間),故終點 + 1。
return s.substring(finalStart, finalEnd + 1);
}
}
```

Python:

Expand Down