mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-08 16:54:50 +08:00
Merge branch 'youngyangyang04:master' into master
This commit is contained in:
@ -337,5 +337,48 @@ object Solution {
|
||||
}
|
||||
```
|
||||
|
||||
PHP:
|
||||
```php
|
||||
//虚拟头结点
|
||||
function swapPairs($head) {
|
||||
if ($head == null || $head->next == null) {
|
||||
return $head;
|
||||
}
|
||||
|
||||
$dummyNode = new ListNode(0, $head);
|
||||
$preNode = $dummyNode; //虚拟头结点
|
||||
$curNode = $head;
|
||||
$nextNode = $head->next;
|
||||
while($curNode && $nextNode) {
|
||||
$nextNextNode = $nextNode->next; //存下一个节点
|
||||
$nextNode->next = $curNode; //交换curHead 和 nextHead
|
||||
$curNode->next = $nextNextNode;
|
||||
$preNode->next = $nextNode; //上一个节点的下一个指向指向nextHead
|
||||
|
||||
//更新当前的几个指针
|
||||
$preNode = $preNode->next->next;
|
||||
$curNode = $nextNextNode;
|
||||
$nextNode = $nextNextNode->next;
|
||||
}
|
||||
|
||||
return $dummyNode->next;
|
||||
}
|
||||
|
||||
//递归版本
|
||||
function swapPairs($head)
|
||||
{
|
||||
// 终止条件
|
||||
if ($head === null || $head->next === null) {
|
||||
return $head;
|
||||
}
|
||||
|
||||
//结果要返回的头结点
|
||||
$next = $head->next;
|
||||
$head->next = $this->swapPairs($next->next); //当前头结点->next指向更新
|
||||
$next->next = $head; //当前第二个节点的->next指向更新
|
||||
return $next; //返回翻转后的头结点
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -146,7 +146,7 @@ public:
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 相关题目推荐
|
||||
|
||||
* 26.删除排序数组中的重复项
|
||||
@ -154,10 +154,6 @@ public:
|
||||
* 844.比较含退格的字符串
|
||||
* 977.有序数组的平方
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
@ -165,18 +161,35 @@ Java:
|
||||
```java
|
||||
class Solution {
|
||||
public int removeElement(int[] nums, int val) {
|
||||
|
||||
// 快慢指针
|
||||
int fastIndex = 0;
|
||||
int slowIndex;
|
||||
for (slowIndex = 0; fastIndex < nums.length; fastIndex++) {
|
||||
int slowIndex = 0;
|
||||
for (int fastIndex = 0; fastIndex < nums.length; fastIndex++) {
|
||||
if (nums[fastIndex] != val) {
|
||||
nums[slowIndex] = nums[fastIndex];
|
||||
slowIndex++;
|
||||
}
|
||||
}
|
||||
return slowIndex;
|
||||
|
||||
}
|
||||
}
|
||||
```
|
||||
```java
|
||||
//相向双指针法
|
||||
class Solution {
|
||||
public int removeElement(int[] nums, int val) {
|
||||
int left = 0;
|
||||
int right = nums.length - 1;
|
||||
while(right >= 0 && nums[right] == val) right--; //将right移到从右数第一个值不为val的位置
|
||||
while(left <= right) {
|
||||
if(nums[left] == val) { //left位置的元素需要移除
|
||||
//将right位置的元素移到left(覆盖),right位置移除
|
||||
nums[left] = nums[right];
|
||||
right--;
|
||||
}
|
||||
left++;
|
||||
while(right >= 0 && nums[right] == val) right--;
|
||||
}
|
||||
return left;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
@ -226,7 +226,32 @@ class Solution {
|
||||
}
|
||||
}
|
||||
```
|
||||
```java
|
||||
//第二种二分法:左闭右开
|
||||
public int searchInsert(int[] nums, int target) {
|
||||
int left = 0;
|
||||
int right = nums.length;
|
||||
while (left < right) { //左闭右开 [left, right)
|
||||
int middle = left + ((right - left) >> 1);
|
||||
if (nums[middle] > target) {
|
||||
right = middle; // target 在左区间,在[left, middle)中
|
||||
} else if (nums[middle] < target) {
|
||||
left = middle + 1; // target 在右区间,在 [middle+1, right)中
|
||||
} else { // nums[middle] == target
|
||||
return middle; // 数组中找到目标值的情况,直接返回下标
|
||||
}
|
||||
}
|
||||
// 目标值在数组所有元素之前 [0,0)
|
||||
// 目标值插入数组中的位置 [left, right) ,return right 即可
|
||||
// 目标值在数组所有元素之后的情况 [left, right),因为是右开区间,所以 return right
|
||||
return right;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
Golang:
|
||||
|
||||
```golang
|
||||
// 第一种二分法
|
||||
func searchInsert(nums []int, target int) int {
|
||||
|
@ -114,7 +114,7 @@ vector<vector<int>> result; // 存放符合条件结果的集合
|
||||
vector<int> path; // 用来存放符合条件结果
|
||||
```
|
||||
|
||||
其实不定义这两个全局遍历也是可以的,把这两个变量放进递归函数的参数里,但函数里参数太多影响可读性,所以我定义全局变量了。
|
||||
其实不定义这两个全局变量也是可以的,把这两个变量放进递归函数的参数里,但函数里参数太多影响可读性,所以我定义全局变量了。
|
||||
|
||||
函数里一定有两个参数,既然是集合n里面取k的数,那么n和k是两个int型的参数。
|
||||
|
||||
|
@ -252,6 +252,24 @@ function numTrees(n: number): number {
|
||||
};
|
||||
```
|
||||
|
||||
### Rust
|
||||
|
||||
```Rust
|
||||
impl Solution {
|
||||
pub fn num_trees(n: i32) -> i32 {
|
||||
let n = n as usize;
|
||||
let mut dp = vec![0; n + 1];
|
||||
dp[0] = 1;
|
||||
for i in 1..=n {
|
||||
for j in 1..=i {
|
||||
dp[i] += dp[j - 1] * dp[i - j];
|
||||
}
|
||||
}
|
||||
dp[n]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### C
|
||||
|
||||
```c
|
||||
|
@ -206,6 +206,65 @@ public:
|
||||
return result;
|
||||
}
|
||||
};
|
||||
```
|
||||
# 优化
|
||||
|
||||
上面的代码还存在一定的优化空间, 在于如何更高效的计算一个子字符串是否是回文字串。上述代码```isPalindrome```函数运用双指针的方法来判定对于一个字符串```s```, 给定起始下标和终止下标, 截取出的子字符串是否是回文字串。但是其中有一定的重复计算存在:
|
||||
|
||||
例如给定字符串```"abcde"```, 在已知```"bcd"```不是回文字串时, 不再需要去双指针操作```"abcde"```而可以直接判定它一定不是回文字串。
|
||||
|
||||
具体来说, 给定一个字符串`s`, 长度为```n```, 它成为回文字串的充分必要条件是```s[0] == s[n-1]```且```s[1:n-1]```是回文字串。
|
||||
|
||||
大家如果熟悉动态规划这种算法的话, 我们可以高效地事先一次性计算出, 针对一个字符串```s```, 它的任何子串是否是回文字串, 然后在我们的回溯函数中直接查询即可, 省去了双指针移动判定这一步骤.
|
||||
|
||||
具体参考代码如下:
|
||||
|
||||
```CPP
|
||||
class Solution {
|
||||
private:
|
||||
vector<vector<string>> result;
|
||||
vector<string> path; // 放已经回文的子串
|
||||
vector<vector<bool>> isPalindrome; // 放事先计算好的是否回文子串的结果
|
||||
void backtracking (const string& s, int startIndex) {
|
||||
// 如果起始位置已经大于s的大小,说明已经找到了一组分割方案了
|
||||
if (startIndex >= s.size()) {
|
||||
result.push_back(path);
|
||||
return;
|
||||
}
|
||||
for (int i = startIndex; i < s.size(); i++) {
|
||||
if (isPalindrome[startIndex][i]) { // 是回文子串
|
||||
// 获取[startIndex,i]在s中的子串
|
||||
string str = s.substr(startIndex, i - startIndex + 1);
|
||||
path.push_back(str);
|
||||
} else { // 不是回文,跳过
|
||||
continue;
|
||||
}
|
||||
backtracking(s, i + 1); // 寻找i+1为起始位置的子串
|
||||
path.pop_back(); // 回溯过程,弹出本次已经填在的子串
|
||||
}
|
||||
}
|
||||
void computePalindrome(const string& s) {
|
||||
// isPalindrome[i][j] 代表 s[i:j](双边包括)是否是回文字串
|
||||
isPalindrome.resize(s.size(), vector<bool>(s.size(), false)); // 根据字符串s, 刷新布尔矩阵的大小
|
||||
for (int i = s.size() - 1; i >= 0; i--) {
|
||||
// 需要倒序计算, 保证在i行时, i+1行已经计算好了
|
||||
for (int j = i; j < s.size(); j++) {
|
||||
if (j == i) {isPalindrome[i][j] = true;}
|
||||
else if (j - i == 1) {isPalindrome[i][j] = (s[i] == s[j]);}
|
||||
else {isPalindrome[i][j] = (s[i] == s[j] && isPalindrome[i+1][j-1]);}
|
||||
}
|
||||
}
|
||||
}
|
||||
public:
|
||||
vector<vector<string>> partition(string s) {
|
||||
result.clear();
|
||||
path.clear();
|
||||
computePalindrome(s);
|
||||
backtracking(s, 0);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
# 总结
|
||||
|
@ -65,6 +65,8 @@
|
||||
|
||||
# 思路
|
||||
|
||||
《代码随想录》算法视频公开课:[栈的最后表演! | LeetCode:150. 逆波兰表达式求值](https://www.bilibili.com/video/BV1kd4y1o7on),相信结合视频在看本篇题解,更有助于大家对本题的理解。
|
||||
|
||||
在上一篇文章中[1047.删除字符串中的所有相邻重复项](https://programmercarl.com/1047.删除字符串中的所有相邻重复项.html)提到了 递归就是用栈来实现的。
|
||||
|
||||
所以**栈与递归之间在某种程度上是可以转换的!** 这一点我们在后续讲解二叉树的时候,会更详细的讲解到。
|
||||
|
@ -32,6 +32,8 @@
|
||||
|
||||
# 思路
|
||||
|
||||
《代码随想录》算法视频公开课:[单调队列正式登场!| LeetCode:239. 滑动窗口最大值](https://www.bilibili.com/video/BV1XS4y1p7qj),相信结合视频在看本篇题解,更有助于大家对本题的理解。
|
||||
|
||||
这是使用单调队列的经典题目。
|
||||
|
||||
难点是如何求一个区间里的最大值呢? (这好像是废话),暴力一下不就得了。
|
||||
|
@ -192,7 +192,7 @@ public:
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
### Java
|
||||
### Java
|
||||
```Java
|
||||
class Solution {
|
||||
public int integerBreak(int n) {
|
||||
@ -259,6 +259,21 @@ func max(a,b int) int{
|
||||
}
|
||||
```
|
||||
|
||||
### Rust
|
||||
```rust
|
||||
pub fn integer_break(n: i32) -> i32 {
|
||||
let n = n as usize;
|
||||
let mut dp = vec![0; n + 1];
|
||||
dp[2] = 1;
|
||||
for i in 3..=n {
|
||||
for j in 1..i-1 {
|
||||
dp[i] = dp[i].max((i - j) * j).max(dp[i - j] * j);
|
||||
}
|
||||
}
|
||||
dp[n] as i32
|
||||
}
|
||||
```
|
||||
|
||||
### Javascript
|
||||
```Javascript
|
||||
var integerBreak = function(n) {
|
||||
@ -299,6 +314,27 @@ function integerBreak(n: number): number {
|
||||
};
|
||||
```
|
||||
|
||||
### Rust
|
||||
|
||||
```Rust
|
||||
impl Solution {
|
||||
fn max(a: i32, b: i32) -> i32{
|
||||
if a > b { a } else { b }
|
||||
}
|
||||
pub fn integer_break(n: i32) -> i32 {
|
||||
let n = n as usize;
|
||||
let mut dp = vec![0; n + 1];
|
||||
dp[2] = 1;
|
||||
for i in 3..=n {
|
||||
for j in 1..i - 1 {
|
||||
dp[i] = Self::max(dp[i], Self::max(((i - j) * j) as i32, dp[i - j] * j as i32));
|
||||
}
|
||||
}
|
||||
dp[n]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### C
|
||||
|
||||
```c
|
||||
|
@ -31,6 +31,14 @@
|
||||
|
||||
# 思路
|
||||
|
||||
《代码随想录》算法视频公开课:[优先级队列正式登场!大顶堆、小顶堆该怎么用?| LeetCode:347.前 K 个高频元素](https://www.bilibili.com/video/BV1Xg41167Lz),相信结合视频在看本篇题解,更有助于大家对本题的理解。
|
||||
|
||||
<p align="center">
|
||||
<iframe src="//player.bilibili.com/player.html?aid=514643371&bvid=BV1Xg41167Lz&cid=808260290&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width=750 height=500> </iframe>
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
这道题目主要涉及到如下三块内容:
|
||||
1. 要统计元素出现频率
|
||||
2. 对频率排序
|
||||
|
@ -266,22 +266,58 @@ class Solution:
|
||||
|
||||
### Go
|
||||
|
||||
**贪心**
|
||||
```golang
|
||||
func wiggleMaxLength(nums []int) int {
|
||||
var count,preDiff,curDiff int
|
||||
count=1
|
||||
if len(nums)<2{
|
||||
return count
|
||||
}
|
||||
for i:=0;i<len(nums)-1;i++{
|
||||
curDiff=nums[i+1]-nums[i]
|
||||
//如果有正有负则更新下标值||或者只有前一个元素为0(针对两个不等元素的序列也视作摆动序列,且摆动长度为2)
|
||||
if (curDiff > 0 && preDiff <= 0) || (preDiff >= 0 && curDiff < 0){
|
||||
preDiff=curDiff
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count
|
||||
var count, preDiff, curDiff int //初始化默认为0
|
||||
count = 1 // 初始化为1,因为最小的序列是1个数
|
||||
if len(nums) < 2 {
|
||||
return count
|
||||
}
|
||||
for i := 0; i < len(nums)-1; i++ {
|
||||
curDiff = nums[i+1] - nums[i]
|
||||
if (curDiff > 0 && preDiff <= 0) || (curDiff < 0 && preDiff >= 0) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
```
|
||||
|
||||
**动态规划**
|
||||
```golang
|
||||
func wiggleMaxLength(nums []int) int {
|
||||
n := len(nums)
|
||||
if n <= 1 {
|
||||
return n
|
||||
}
|
||||
dp := make([][2]int, n)
|
||||
// i 0 作为波峰的最大长度
|
||||
// i 1 作为波谷的最大长度
|
||||
dp[0][0] = 1
|
||||
dp[0][1] = 1
|
||||
for i := 0; i < n; i++ {
|
||||
for j := 0; j < i; j++ {
|
||||
if nums[j] > nums[i] { //nums[i]为波谷
|
||||
dp[i][1] = max(dp[i][1], dp[j][0]+1)
|
||||
}
|
||||
if nums[j] < nums[i] { //nums[i]为波峰 或者相等
|
||||
dp[i][0] = max(dp[i][0], dp[j][1]+1)
|
||||
}
|
||||
if nums[j] == nums[i] { //添加一种情况,nums[i]为相等
|
||||
dp[i][0] = max(dp[i][0], dp[j][0]) //波峰
|
||||
dp[i][1] = max(dp[i][1], dp[j][1]) //波谷
|
||||
}
|
||||
}
|
||||
}
|
||||
return max(dp[n-1][0], dp[n-1][1])
|
||||
}
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
} else {
|
||||
return b
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -417,7 +417,32 @@ var canPartition = function(nums) {
|
||||
```
|
||||
|
||||
|
||||
### Rust
|
||||
|
||||
```Rust
|
||||
impl Solution {
|
||||
fn max(a: usize, b: usize) -> usize {
|
||||
if a > b { a } else { b }
|
||||
}
|
||||
pub fn can_partition(nums: Vec<i32>) -> bool {
|
||||
let nums = nums.iter().map(|x| *x as usize).collect::<Vec<usize>>();
|
||||
let mut sum = 0;
|
||||
let mut dp: Vec<usize> = vec![0; 10001];
|
||||
for i in 0..nums.len() {
|
||||
sum += nums[i];
|
||||
}
|
||||
if sum % 2 == 1 { return false; }
|
||||
let target = sum / 2;
|
||||
for i in 0..nums.len() {
|
||||
for j in (nums[i]..=target).rev() {
|
||||
dp[j] = Self::max(dp[j], dp[j - nums[i]] + nums[i]);
|
||||
}
|
||||
}
|
||||
if dp[target] == target { return true; }
|
||||
false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### C:
|
||||
|
@ -16,6 +16,17 @@
|
||||
|
||||
# 思路
|
||||
|
||||
这道题目也是 dfs bfs基础类题目。
|
||||
|
||||
|
||||
## DFS
|
||||
|
||||
很多同学,写dfs其实也是凭感觉来,有的时候dfs函数中写终止条件才能过,有的时候 dfs函数不写终止添加也能过!
|
||||
|
||||
这里其实涉及到dfs的两种写法,
|
||||
|
||||
以下代码使用dfs实现,如果对dfs不太了解的话,建议先看这篇题解:[797.所有可能的路径](https://leetcode.cn/problems/all-paths-from-source-to-target/solution/by-carlsun-2-66pf/),
|
||||
|
||||
写法一,dfs只处理下一个节点
|
||||
```CPP
|
||||
class Solution {
|
||||
@ -94,3 +105,55 @@ public:
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
以上两种写法的区别,我在题解: [DFS,BDF 你没注意的细节都给你列出来了!LeetCode:200. 岛屿数量](https://leetcode.cn/problems/number-of-islands/solution/by-carlsun-2-n72a/)做了详细介绍。
|
||||
|
||||
## BFS
|
||||
|
||||
```CPP
|
||||
class Solution {
|
||||
private:
|
||||
int count;
|
||||
int dir[4][2] = {0, 1, 1, 0, -1, 0, 0, -1}; // 四个方向
|
||||
void bfs(vector<vector<int>>& grid, vector<vector<bool>>& visited, int x, int y) {
|
||||
queue<int> que;
|
||||
que.push(x);
|
||||
que.push(y);
|
||||
visited[x][y] = true; // 加入队列就意味节点是陆地可到达的点
|
||||
count++;
|
||||
while(!que.empty()) {
|
||||
int xx = que.front();que.pop();
|
||||
int yy = que.front();que.pop();
|
||||
for (int i = 0 ;i < 4; i++) {
|
||||
int nextx = xx + dir[i][0];
|
||||
int nexty = yy + dir[i][1];
|
||||
if (nextx < 0 || nextx >= grid.size() || nexty < 0 || nexty >= grid[0].size()) continue; // 越界
|
||||
if (!visited[nextx][nexty] && grid[nextx][nexty] == 1) { // 节点没有被访问过且是陆地
|
||||
visited[nextx][nexty] = true;
|
||||
count++;
|
||||
que.push(nextx);
|
||||
que.push(nexty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
int maxAreaOfIsland(vector<vector<int>>& grid) {
|
||||
int n = grid.size(), m = grid[0].size();
|
||||
vector<vector<bool>> visited = vector<vector<bool>>(n, vector<bool>(m, false));
|
||||
int result = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
for (int j = 0; j < m; j++) {
|
||||
if (!visited[i][j] && grid[i][j] == 1) {
|
||||
count = 0;
|
||||
bfs(grid, visited, i, j); // 将与其链接的陆地都标记上 true
|
||||
result = max(result, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
```
|
||||
|
@ -290,10 +290,11 @@ func search(nums []int, target int) int {
|
||||
*/
|
||||
var search = function(nums, target) {
|
||||
// right是数组最后一个数的下标,num[right]在查找范围内,是左闭右闭区间
|
||||
let left = 0, right = nums.length - 1;
|
||||
let mid, left = 0, right = nums.length - 1;
|
||||
// 当left=right时,由于nums[right]在查找范围内,所以要包括此情况
|
||||
while (left <= right) {
|
||||
let mid = left + Math.floor((right - left)/2);
|
||||
// 位运算 + 防止大数溢出
|
||||
mid = left + ((right - left) >> 1);
|
||||
// 如果中间数大于目标值,要把中间数排除查找范围,所以右边界更新为mid-1;如果右边界更新为mid,那中间数还在下次查找范围内
|
||||
if (nums[mid] > target) {
|
||||
right = mid - 1; // 去左面闭区间寻找
|
||||
@ -316,10 +317,11 @@ var search = function(nums, target) {
|
||||
*/
|
||||
var search = function(nums, target) {
|
||||
// right是数组最后一个数的下标+1,nums[right]不在查找范围内,是左闭右开区间
|
||||
let left = 0, right = nums.length;
|
||||
let mid, left = 0, right = nums.length;
|
||||
// 当left=right时,由于nums[right]不在查找范围,所以不必包括此情况
|
||||
while (left < right) {
|
||||
let mid = left + Math.floor((right - left)/2);
|
||||
// 位运算 + 防止大数溢出
|
||||
mid = left + ((right - left) >> 1);
|
||||
// 如果中间值大于目标值,中间值不应在下次查找的范围内,但中间值的前一个值应在;
|
||||
// 由于right本来就不在查找范围内,所以将右边界更新为中间值,如果更新右边界为mid-1则将中间值的前一个值也踢出了下次寻找范围
|
||||
if (nums[mid] > target) {
|
||||
@ -340,9 +342,10 @@ var search = function(nums, target) {
|
||||
|
||||
```typescript
|
||||
function search(nums: number[], target: number): number {
|
||||
let left: number = 0, right: number = nums.length - 1;
|
||||
let mid: number, left: number = 0, right: number = nums.length - 1;
|
||||
while (left <= right) {
|
||||
let mid: number = left + Math.floor((right - left) / 2);
|
||||
// 位运算 + 防止大数溢出
|
||||
mid = left + ((right - left) >> 1);
|
||||
if (nums[mid] > target) {
|
||||
right = mid - 1;
|
||||
} else if (nums[mid] < target) {
|
||||
@ -359,9 +362,10 @@ function search(nums: number[], target: number): number {
|
||||
|
||||
```typescript
|
||||
function search(nums: number[], target: number): number {
|
||||
let left: number = 0, right: number = nums.length;
|
||||
let mid: number, left: number = 0, right: number = nums.length;
|
||||
while (left < right) {
|
||||
let mid: number = left + Math.floor((right - left) / 2);
|
||||
// 位运算 + 防止大数溢出
|
||||
mid = left +((right - left) >> 1);
|
||||
if (nums[mid] > target) {
|
||||
right = mid;
|
||||
} else if (nums[mid] < target) {
|
||||
|
@ -147,6 +147,59 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
### java
|
||||
|
||||
```java
|
||||
//方法一:采用额外的数组空间
|
||||
class Solution {
|
||||
public int[] sortArrayByParityII(int[] nums) {
|
||||
//定义结果数组 result
|
||||
int[] result = new int[nums.length];
|
||||
int even = 0, odd = 1;
|
||||
for(int i = 0; i < nums.length; i++){
|
||||
//如果为偶数
|
||||
if(nums[i] % 2 == 0){
|
||||
result[even] = nums[i];
|
||||
even += 2;
|
||||
}else{
|
||||
result[odd] = nums[i];
|
||||
odd += 2;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
```
|
||||
```java
|
||||
//方法二:不采用额外的数组空间
|
||||
class Solution922 {
|
||||
public int[] sortArrayByParityII(int[] nums) {
|
||||
//定义双指针
|
||||
int oddPoint = 1, evenPoint = 0;
|
||||
//开始移动并交换,最后一层必然为相互交换后再移动或者相同直接移动
|
||||
while(oddPoint < nums.length && evenPoint < nums.length){
|
||||
//进行判断
|
||||
if(nums[oddPoint] % 2 == 0 && nums[evenPoint] % 2 == 1){ //如果均不满足
|
||||
int temp = 0;
|
||||
temp = nums[oddPoint];
|
||||
nums[oddPoint] = nums[evenPoint];
|
||||
nums[evenPoint] = temp;
|
||||
oddPoint += 2;
|
||||
evenPoint += 2;
|
||||
}else if(nums[oddPoint] % 2 == 0 && nums[evenPoint] % 2 == 0){ //偶数满足
|
||||
evenPoint += 2;
|
||||
}else if(nums[oddPoint] % 2 == 1 && nums[evenPoint] % 2 == 1){ //奇数满足
|
||||
oddPoint += 2;
|
||||
}else{
|
||||
oddPoint += 2;
|
||||
evenPoint += 2;
|
||||
}
|
||||
}
|
||||
return nums;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Python3
|
||||
|
||||
```python
|
||||
|
@ -5,7 +5,9 @@
|
||||
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
# 面试题 02.07. 链表相交
|
||||
# 面试题 02.07. 链表相交
|
||||
|
||||
同:160.链表相交
|
||||
|
||||
[力扣题目链接](https://leetcode.cn/problems/intersection-of-two-linked-lists-lcci/)
|
||||
|
||||
|
25
添加0222.完全二叉树的节点个数Go版本.md
Normal file
25
添加0222.完全二叉树的节点个数Go版本.md
Normal file
@ -0,0 +1,25 @@
|
||||
```go
|
||||
func countNodes(root *TreeNode) int {
|
||||
if root == nil {
|
||||
return 0
|
||||
}
|
||||
q := list.New()
|
||||
q.PushBack(root)
|
||||
res := 0
|
||||
for q.Len() > 0 {
|
||||
n := q.Len()
|
||||
for i := 0; i < n; i++ {
|
||||
node := q.Remove(q.Front()).(*TreeNode)
|
||||
if node.Left != nil {
|
||||
q.PushBack(node.Left)
|
||||
}
|
||||
if node.Right != nil {
|
||||
q.PushBack(node.Right)
|
||||
}
|
||||
res++
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
```
|
||||
|
22
添加559.n叉树的最大深度Go版本.md
Normal file
22
添加559.n叉树的最大深度Go版本.md
Normal file
@ -0,0 +1,22 @@
|
||||
```go
|
||||
func maxDepth(root *Node) int {
|
||||
if root == nil {
|
||||
return 0
|
||||
}
|
||||
q := list.New()
|
||||
q.PushBack(root)
|
||||
depth := 0
|
||||
for q.Len() > 0 {
|
||||
n := q.Len()
|
||||
for i := 0; i < n; i++ {
|
||||
node := q.Remove(q.Front()).(*Node)
|
||||
for j := range node.Children {
|
||||
q.PushBack(node.Children[j])
|
||||
}
|
||||
}
|
||||
depth++
|
||||
}
|
||||
return depth
|
||||
}
|
||||
```
|
||||
|
Reference in New Issue
Block a user