mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-08 16:54:50 +08:00
Merge branch 'youngyangyang04:master' into zhicheng-lee-patch-4
This commit is contained in:
@ -158,6 +158,57 @@ class Solution:
|
||||
return 0
|
||||
```
|
||||
## Go
|
||||
```go
|
||||
func ladderLength(beginWord string, endWord string, wordList []string) int {
|
||||
wordMap, que, depth := getWordMap(wordList, beginWord), []string{beginWord}, 0
|
||||
for len(que) > 0 {
|
||||
depth++
|
||||
qLen := len(que) // 单词的长度
|
||||
for i := 0; i < qLen; i++ {
|
||||
word := que[0]
|
||||
que = que[1:] // 首位单词出队
|
||||
candidates := getCandidates(word)
|
||||
for _, candidate := range candidates {
|
||||
if _, exist := wordMap[candidate]; exist { // 用生成的结果集去查询
|
||||
if candidate == endWord {
|
||||
return depth + 1
|
||||
}
|
||||
delete(wordMap, candidate) // 删除集合中的用过的结果
|
||||
que = append(que, candidate)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
// 获取单词Map为后续的查询增加速度
|
||||
func getWordMap(wordList []string, beginWord string) map[string]int {
|
||||
wordMap := make(map[string]int)
|
||||
for i, word := range wordList {
|
||||
if _, exist := wordMap[word]; !exist {
|
||||
if word != beginWord {
|
||||
wordMap[word] = i
|
||||
}
|
||||
}
|
||||
}
|
||||
return wordMap
|
||||
}
|
||||
|
||||
// 用26个英文字母分别替换掉各个位置的字母,生成一个结果集
|
||||
func getCandidates(word string) []string {
|
||||
var res []string
|
||||
for i := 0; i < 26; i++ {
|
||||
for j := 0; j < len(word); j++ {
|
||||
if word[j] != byte(int('a')+i) {
|
||||
res = append(res, word[:j]+string(int('a')+i)+word[j+1:])
|
||||
}
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
```
|
||||
|
||||
## JavaScript
|
||||
```javascript
|
||||
|
@ -247,3 +247,35 @@ public:
|
||||
|
||||
|
||||
## 其他语言版本
|
||||
|
||||
### Java
|
||||
|
||||
下面的代码使用的是深度优先搜索 DFS 的做法。为了统计岛屿数量同时不重复记录,每当我们搜索到一个岛后,就将这个岛 “淹没” —— 将这个岛所占的地方从 “1” 改为 “0”,这样就不用担心后续会重复记录这个岛屿了。而 DFS 的过程就体现在 “淹没” 这一步中。详见代码:
|
||||
|
||||
```java
|
||||
public int numIslands(char[][] grid) {
|
||||
int res = 0; //记录找到的岛屿数量
|
||||
for(int i = 0;i < grid.length;i++){
|
||||
for(int j = 0;j < grid[0].length;j++){
|
||||
//找到“1”,res加一,同时淹没这个岛
|
||||
if(grid[i][j] == '1'){
|
||||
res++;
|
||||
dfs(grid,i,j);
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
//使用DFS“淹没”岛屿
|
||||
public void dfs(char[][] grid, int i, int j){
|
||||
//搜索边界:索引越界或遍历到了"0"
|
||||
if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == '0') return;
|
||||
//将这块土地标记为"0"
|
||||
grid[i][j] = '0';
|
||||
//根据"每座岛屿只能由水平方向或竖直方向上相邻的陆地连接形成",对上下左右的相邻顶点进行dfs
|
||||
dfs(grid,i - 1,j);
|
||||
dfs(grid,i + 1,j);
|
||||
dfs(grid,i,j + 1);
|
||||
dfs(grid,i,j - 1);
|
||||
}
|
||||
```
|
@ -92,18 +92,24 @@ public:
|
||||
|
||||
Java:
|
||||
```java
|
||||
/**
|
||||
* 242. 有效的字母异位词 字典解法
|
||||
* 时间复杂度O(m+n) 空间复杂度O(1)
|
||||
*/
|
||||
class Solution {
|
||||
public boolean isAnagram(String s, String t) {
|
||||
|
||||
int[] record = new int[26];
|
||||
for (char c : s.toCharArray()) {
|
||||
record[c - 'a'] += 1;
|
||||
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
record[s.charAt(i) - 'a']++;
|
||||
}
|
||||
for (char c : t.toCharArray()) {
|
||||
record[c - 'a'] -= 1;
|
||||
|
||||
for (int i = 0; i < t.length(); i++) {
|
||||
record[t.charAt(i) - 'a']--;
|
||||
}
|
||||
for (int i : record) {
|
||||
if (i != 0) {
|
||||
|
||||
for (int count: record) {
|
||||
if (count != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -140,24 +140,55 @@ public:
|
||||
Java:
|
||||
```java
|
||||
|
||||
/*Comparator接口说明:
|
||||
* 返回负数,形参中第一个参数排在前面;返回正数,形参中第二个参数排在前面
|
||||
* 对于队列:排在前面意味着往队头靠
|
||||
* 对于堆(使用PriorityQueue实现):从队头到队尾按从小到大排就是最小堆(小顶堆),
|
||||
* 从队头到队尾按从大到小排就是最大堆(大顶堆)--->队头元素相当于堆的根节点
|
||||
* */
|
||||
class Solution {
|
||||
public int[] topKFrequent(int[] nums, int k) {
|
||||
int[] result = new int[k];
|
||||
HashMap<Integer, Integer> map = new HashMap<>();
|
||||
for (int num : nums) {
|
||||
map.put(num, map.getOrDefault(num, 0) + 1);
|
||||
//解法1:基于大顶堆实现
|
||||
public int[] topKFrequent1(int[] nums, int k) {
|
||||
Map<Integer,Integer> map = new HashMap<>();//key为数组元素值,val为对应出现次数
|
||||
for(int num:nums){
|
||||
map.put(num,map.getOrDefault(num,0)+1);
|
||||
}
|
||||
|
||||
Set<Map.Entry<Integer, Integer>> entries = map.entrySet();
|
||||
// 根据map的value值,构建于一个大顶堆(o1 - o2: 小顶堆, o2 - o1 : 大顶堆)
|
||||
PriorityQueue<Map.Entry<Integer, Integer>> queue = new PriorityQueue<>((o1, o2) -> o2.getValue() - o1.getValue());
|
||||
for (Map.Entry<Integer, Integer> entry : entries) {
|
||||
queue.offer(entry);
|
||||
//在优先队列中存储二元组(num,cnt),cnt表示元素值num在数组中的出现次数
|
||||
//出现次数按从队头到队尾的顺序是从大到小排,出现次数最多的在队头(相当于大顶堆)
|
||||
PriorityQueue<int[]> pq = new PriorityQueue<>((pair1, pair2)->pair2[1]-pair1[1]);
|
||||
for(Map.Entry<Integer,Integer> entry:map.entrySet()){//大顶堆需要对所有元素进行排序
|
||||
pq.add(new int[]{entry.getKey(),entry.getValue()});
|
||||
}
|
||||
for (int i = k - 1; i >= 0; i--) {
|
||||
result[i] = queue.poll().getKey();
|
||||
int[] ans = new int[k];
|
||||
for(int i=0;i<k;i++){//依次从队头弹出k个,就是出现频率前k高的元素
|
||||
ans[i] = pq.poll()[0];
|
||||
}
|
||||
return result;
|
||||
return ans;
|
||||
}
|
||||
//解法2:基于小顶堆实现
|
||||
public int[] topKFrequent2(int[] nums, int k) {
|
||||
Map<Integer,Integer> map = new HashMap<>();//key为数组元素值,val为对应出现次数
|
||||
for(int num:nums){
|
||||
map.put(num,map.getOrDefault(num,0)+1);
|
||||
}
|
||||
//在优先队列中存储二元组(num,cnt),cnt表示元素值num在数组中的出现次数
|
||||
//出现次数按从队头到队尾的顺序是从小到大排,出现次数最低的在队头(相当于小顶堆)
|
||||
PriorityQueue<int[]> pq = new PriorityQueue<>((pair1,pair2)->pair1[1]-pair2[1]);
|
||||
for(Map.Entry<Integer,Integer> entry:map.entrySet()){//小顶堆只需要维持k个元素有序
|
||||
if(pq.size()<k){//小顶堆元素个数小于k个时直接加
|
||||
pq.add(new int[]{entry.getKey(),entry.getValue()});
|
||||
}else{
|
||||
if(entry.getValue()>pq.peek()[1]){//当前元素出现次数大于小顶堆的根结点(这k个元素中出现次数最少的那个)
|
||||
pq.poll();//弹出队头(小顶堆的根结点),即把堆里出现次数最少的那个删除,留下的就是出现次数多的了
|
||||
pq.add(new int[]{entry.getKey(),entry.getValue()});
|
||||
}
|
||||
}
|
||||
}
|
||||
int[] ans = new int[k];
|
||||
for(int i=k-1;i>=0;i--){//依次弹出小顶堆,先弹出的是堆的根,出现次数少,后面弹出的出现次数多
|
||||
ans[i] = pq.poll()[0];
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
@ -152,6 +152,8 @@ public:
|
||||
for (int i = 0; i < nums.size(); i++) {
|
||||
sum += nums[i];
|
||||
}
|
||||
// 也可以使用库函数一步求和
|
||||
// int sum = accumulate(nums.begin(), nums.end(), 0);
|
||||
if (sum % 2 == 1) return false;
|
||||
int target = sum / 2;
|
||||
|
||||
|
@ -239,18 +239,24 @@ Typescript:
|
||||
|
||||
```typescript
|
||||
function sortedSquares(nums: number[]): number[] {
|
||||
let left: number = 0, right: number = nums.length - 1;
|
||||
let resArr: number[] = new Array(nums.length);
|
||||
let resArrIndex: number = resArr.length - 1;
|
||||
const ans: number[] = [];
|
||||
let left = 0,
|
||||
right = nums.length - 1;
|
||||
|
||||
while (left <= right) {
|
||||
if (Math.abs(nums[left]) < Math.abs(nums[right])) {
|
||||
resArr[resArrIndex] = nums[right--] ** 2;
|
||||
// 右侧的元素不需要取绝对值,nums 为非递减排序的整数数组
|
||||
// 在同为负数的情况下,左侧的平方值一定大于右侧的平方值
|
||||
if (Math.abs(nums[left]) > nums[right]) {
|
||||
// 使用 Array.prototype.unshift() 直接在数组的首项插入当前最大值
|
||||
ans.unshift(nums[left] ** 2);
|
||||
left++;
|
||||
} else {
|
||||
resArr[resArrIndex] = nums[left++] ** 2;
|
||||
ans.unshift(nums[right] ** 2);
|
||||
right--;
|
||||
}
|
||||
resArrIndex--;
|
||||
}
|
||||
return resArr;
|
||||
|
||||
return ans;
|
||||
};
|
||||
```
|
||||
|
||||
|
Reference in New Issue
Block a user