mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-09 19:44:45 +08:00
Merge branch 'master' into master
This commit is contained in:
@ -106,9 +106,56 @@ public int[] twoSum(int[] nums, int target) {
|
||||
|
||||
Python:
|
||||
|
||||
```python3
|
||||
class Solution:
|
||||
def twoSum(self, nums: List[int], target: int) -> List[int]:
|
||||
hashmap={}
|
||||
for ind,num in enumerate(nums):
|
||||
hashmap[num] = ind
|
||||
for i,num in enumerate(nums):
|
||||
j = hashmap.get(target - num)
|
||||
if j is not None and i!=j:
|
||||
return [i,j]
|
||||
```
|
||||
|
||||
|
||||
Go:
|
||||
|
||||
```go
|
||||
func twoSum(nums []int, target int) []int {
|
||||
for k1, _ := range nums {
|
||||
for k2 := k1 + 1; k2 < len(nums); k2++ {
|
||||
if target == nums[k1] + nums[k2] {
|
||||
return []int{k1, k2}
|
||||
}
|
||||
}
|
||||
}
|
||||
return []int{}
|
||||
}
|
||||
```
|
||||
|
||||
Rust
|
||||
|
||||
```rust
|
||||
use std::collections::HashMap;
|
||||
|
||||
impl Solution {
|
||||
pub fn two_sum(nums: Vec<i32>, target: i32) -> Vec<i32> {
|
||||
let mut map = HashMap::with_capacity(nums.len());
|
||||
|
||||
for i in 0..nums.len() {
|
||||
if let Some(k) = map.get(&(target - nums[i])) {
|
||||
if *k != i {
|
||||
return vec![*k as i32, i as i32];
|
||||
}
|
||||
}
|
||||
map.insert(nums[i], i);
|
||||
}
|
||||
panic!("not found")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
@ -116,4 +163,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -178,12 +178,83 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```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;
|
||||
}
|
||||
|
||||
if (i > 0 && nums[i] == nums[i - 1]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int left = i + 1;
|
||||
int right = nums.length - 1;
|
||||
while (right > left) {
|
||||
int sum = nums[i] + nums[left] + nums[right];
|
||||
if (sum > 0) {
|
||||
right--;
|
||||
} else if (sum < 0) {
|
||||
left++;
|
||||
} else {
|
||||
result.add(Arrays.asList(nums[i], nums[left], nums[right]));
|
||||
|
||||
while (right > left && nums[right] == nums[right - 1]) right--;
|
||||
while (right > left && nums[left] == nums[left + 1]) left++;
|
||||
|
||||
right--;
|
||||
left++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
Go:
|
||||
```Go
|
||||
func threeSum(nums []int)[][]int{
|
||||
sort.Ints(nums)
|
||||
res:=[][]int{}
|
||||
|
||||
for i:=0;i<len(nums)-2;i++{
|
||||
n1:=nums[i]
|
||||
if n1>0{
|
||||
break
|
||||
}
|
||||
if i>0&&n1==nums[i-1]{
|
||||
continue
|
||||
}
|
||||
l,r:=i+1,len(nums)-1
|
||||
for l<r{
|
||||
n2,n3:=nums[l],nums[r]
|
||||
if n1+n2+n3==0{
|
||||
res=append(res,[]int{n1,n2,n3})
|
||||
for l<r&&nums[l]==n2{
|
||||
l++
|
||||
}
|
||||
for l<r&&nums[r]==n3{
|
||||
r--
|
||||
}
|
||||
}else if n1+n2+n3<0{
|
||||
l++
|
||||
}else {
|
||||
r--
|
||||
}
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
@ -240,7 +240,46 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```Java
|
||||
class Solution {
|
||||
|
||||
//设置全局列表存储最后的结果
|
||||
List<String> list = new ArrayList<>();
|
||||
|
||||
public List<String> letterCombinations(String digits) {
|
||||
if (digits == null || digits.length() == 0) {
|
||||
return list;
|
||||
}
|
||||
//初始对应所有的数字,为了直接对应2-9,新增了两个无效的字符串""
|
||||
String[] numString = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
|
||||
//迭代处理
|
||||
backTracking(digits, numString, 0);
|
||||
return list;
|
||||
|
||||
}
|
||||
|
||||
//每次迭代获取一个字符串,所以会设计大量的字符串拼接,所以这里选择更为高效的 StringBuild
|
||||
StringBuilder temp = new StringBuilder();
|
||||
|
||||
//比如digits如果为"23",num 为0,则str表示2对应的 abc
|
||||
public void backTracking(String digits, String[] numString, int num) {
|
||||
//遍历全部一次记录一次得到的字符串
|
||||
if (num == digits.length()) {
|
||||
list.add(temp.toString());
|
||||
return;
|
||||
}
|
||||
//str 表示当前num对应的字符串
|
||||
String str = numString[digits.charAt(num) - '0'];
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
temp.append(str.charAt(i));
|
||||
//回溯
|
||||
backTracking(digits, numString, num + 1);
|
||||
//剔除末尾的继续尝试
|
||||
temp.deleteCharAt(temp.length() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
@ -121,7 +121,48 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```Java
|
||||
class Solution {
|
||||
public List<List<Integer>> fourSum(int[] nums, int target) {
|
||||
List<List<Integer>> result = new ArrayList<>();
|
||||
Arrays.sort(nums);
|
||||
|
||||
for (int i = 0; i < nums.length; i++) {
|
||||
|
||||
if (i > 0 && nums[i - 1] == nums[i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int j = i + 1; j < nums.length; j++) {
|
||||
|
||||
if (j > i + 1 && nums[j - 1] == nums[j]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int left = j + 1;
|
||||
int right = nums.length - 1;
|
||||
while (right > left) {
|
||||
int sum = nums[i] + nums[j] + nums[left] + nums[right];
|
||||
if (sum > target) {
|
||||
right--;
|
||||
} else if (sum < target) {
|
||||
left++;
|
||||
} else {
|
||||
result.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
|
||||
|
||||
while (right > left && nums[right] == nums[right - 1]) right--;
|
||||
while (right > left && nums[left] == nums[left + 1]) left++;
|
||||
|
||||
left++;
|
||||
right--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
@ -112,7 +112,28 @@ class Solution {
|
||||
}
|
||||
}
|
||||
```
|
||||
Go:
|
||||
```Go
|
||||
func removeNthFromEnd(head *ListNode, n int) *ListNode {
|
||||
result:=&ListNode{}
|
||||
result.Next=head
|
||||
var pre *ListNode
|
||||
cur:=result
|
||||
|
||||
i:=1
|
||||
for head!=nil{
|
||||
if i>=n{
|
||||
pre=cur
|
||||
cur=cur.Next
|
||||
}
|
||||
head=head.Next
|
||||
i++
|
||||
}
|
||||
pre.Next=pre.Next.Next
|
||||
return result.Next
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
|
@ -138,14 +138,114 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```Java
|
||||
class Solution {
|
||||
public boolean isValid(String s) {
|
||||
Deque<Character> deque = new LinkedList<>();
|
||||
char ch;
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
ch = s.charAt(i);
|
||||
//碰到左括号,就把相应的右括号入栈
|
||||
if (ch == '(') {
|
||||
deque.push(')');
|
||||
}else if (ch == '{') {
|
||||
deque.push('}');
|
||||
}else if (ch == '[') {
|
||||
deque.push(']');
|
||||
} else if (deque.isEmpty() || deque.peek() != ch) {
|
||||
return false;
|
||||
}else {//如果是右括号判断是否和栈顶元素匹配
|
||||
deque.pop();
|
||||
}
|
||||
}
|
||||
//最后判断栈中元素是否匹配
|
||||
return deque.isEmpty();
|
||||
}
|
||||
}
|
||||
// 方法2
|
||||
class Solution {
|
||||
public boolean isValid(String s) {
|
||||
|
||||
Stack<Character> stack = new Stack<>();
|
||||
Map<Character, Character> map = new HashMap<Character, Character>() {
|
||||
{
|
||||
put('}', '{');
|
||||
put(']', '[');
|
||||
put(')', '(');
|
||||
}
|
||||
};
|
||||
|
||||
for (Character c : s.toCharArray()) { // 顺序读取字符
|
||||
if (!stack.isEmpty() && map.containsKey(c)) { // 是右括号 && 栈不为空
|
||||
if (stack.peek() == map.get(c)) { // 取其对应的左括号直接和栈顶比
|
||||
stack.pop(); // 相同则抵消,出栈
|
||||
} else {
|
||||
return false; // 不同则直接返回
|
||||
}
|
||||
} else {
|
||||
stack.push(c); // 左括号,直接入栈
|
||||
}
|
||||
}
|
||||
return stack.isEmpty(); // 看左右是否抵消完
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python3
|
||||
class Solution:
|
||||
def isValid(self, s: str) -> bool:
|
||||
stack = [] # 保存还未匹配的左括号
|
||||
mapping = {")": "(", "]": "[", "}": "{"}
|
||||
for i in s:
|
||||
if i in "([{": # 当前是左括号,则入栈
|
||||
stack.append(i)
|
||||
elif stack and stack[-1] == mapping[i]: # 当前是配对的右括号则出栈
|
||||
stack.pop()
|
||||
else: # 不是匹配的右括号或者没有左括号与之匹配,则返回false
|
||||
return False
|
||||
return stack == [] # 最后必须正好把左括号匹配完
|
||||
```
|
||||
|
||||
Go:
|
||||
```Go
|
||||
func isValid(s string) bool {
|
||||
hash := map[byte]byte{')':'(', ']':'[', '}':'{'}
|
||||
stack := make([]byte, 0)
|
||||
if s == "" {
|
||||
return true
|
||||
}
|
||||
|
||||
for i := 0; i < len(s); i++ {
|
||||
if s[i] == '(' || s[i] == '[' || s[i] == '{' {
|
||||
stack = append(stack, s[i])
|
||||
} else if len(stack) > 0 && stack[len(stack)-1] == hash[s[i]] {
|
||||
stack = stack[:len(stack)-1]
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return len(stack) == 0
|
||||
}
|
||||
```
|
||||
|
||||
Ruby:
|
||||
```ruby
|
||||
def is_valid(strs)
|
||||
symbol_map = {')' => '(', '}' => '{', ']' => '['}
|
||||
stack = []
|
||||
strs.size.times {|i|
|
||||
c = strs[i]
|
||||
if symbol_map.has_key?(c)
|
||||
top_e = stack.shift
|
||||
return false if symbol_map[c] != top_e
|
||||
else
|
||||
stack.unshift(c)
|
||||
end
|
||||
}
|
||||
stack.empty?
|
||||
end
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
140
problems/0024.两两交换链表中的节点.md
Normal file
140
problems/0024.两两交换链表中的节点.md
Normal file
@ -0,0 +1,140 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
## 24. 两两交换链表中的节点
|
||||
|
||||
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
|
||||
|
||||
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
|
||||
|
||||
|
||||
<img src='https://code-thinking.cdn.bcebos.com/pics/24.%E4%B8%A4%E4%B8%A4%E4%BA%A4%E6%8D%A2%E9%93%BE%E8%A1%A8%E4%B8%AD%E7%9A%84%E8%8A%82%E7%82%B9-%E9%A2%98%E6%84%8F.jpg' width=600 alt='24.两两交换链表中的节点-题意'> </img></div>
|
||||
|
||||
## 思路
|
||||
|
||||
这道题目正常模拟就可以了。
|
||||
|
||||
建议使用虚拟头结点,这样会方便很多,要不然每次针对头结点(没有前一个指针指向头结点),还要单独处理。
|
||||
|
||||
对虚拟头结点的操作,还不熟悉的话,可以看这篇[链表:听说用虚拟头节点会方便很多?](https://mp.weixin.qq.com/s/L5aanfALdLEwVWGvyXPDqA)。
|
||||
|
||||
接下来就是交换相邻两个元素了,**此时一定要画图,不画图,操作多个指针很容易乱,而且要操作的先后顺序**
|
||||
|
||||
初始时,cur指向虚拟头结点,然后进行如下三步:
|
||||
|
||||

|
||||
|
||||
操作之后,链表如下:
|
||||
|
||||

|
||||
|
||||
看这个可能就更直观一些了:
|
||||
|
||||
|
||||

|
||||
|
||||
对应的C++代码实现如下: (注释中详细和如上图中的三步做对应)
|
||||
|
||||
```C++
|
||||
class Solution {
|
||||
public:
|
||||
ListNode* swapPairs(ListNode* head) {
|
||||
ListNode* dummyHead = new ListNode(0); // 设置一个虚拟头结点
|
||||
dummyHead->next = head; // 将虚拟头结点指向head,这样方面后面做删除操作
|
||||
ListNode* cur = dummyHead;
|
||||
while(cur->next != nullptr && cur->next->next != nullptr) {
|
||||
ListNode* tmp = cur->next; // 记录临时节点
|
||||
ListNode* tmp1 = cur->next->next->next; // 记录临时节点
|
||||
|
||||
cur->next = cur->next->next; // 步骤一
|
||||
cur->next->next = tmp; // 步骤二
|
||||
cur->next->next->next = tmp1; // 步骤三
|
||||
|
||||
cur = cur->next->next; // cur移动两位,准备下一轮交换
|
||||
}
|
||||
return dummyHead->next;
|
||||
}
|
||||
};
|
||||
```
|
||||
* 时间复杂度:$O(n)$
|
||||
* 空间复杂度:$O(1)$
|
||||
|
||||
## 拓展
|
||||
|
||||
**这里还是说一下,大家不必太在意力扣上执行用时,打败多少多少用户,这个统计不准确的。**
|
||||
|
||||
做题的时候自己能分析出来时间复杂度就可以了,至于力扣上执行用时,大概看一下就行。
|
||||
|
||||
上面的代码我第一次提交执行用时8ms,打败6.5%的用户,差点吓到我了。
|
||||
|
||||
心想应该没有更好的方法了吧,也就O(n)的时间复杂度,重复提交几次,这样了:
|
||||
|
||||

|
||||
|
||||
力扣上的统计如果两份代码是 100ms 和 300ms的耗时,其实是需要注意的。
|
||||
|
||||
如果一个是 4ms 一个是 12ms,看上去好像是一个打败了80%,一个打败了20%,其实是没有差别的。 只不过是力扣上统计的误差而已。
|
||||
|
||||
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
// 递归版本
|
||||
class Solution {
|
||||
public ListNode swapPairs(ListNode head) {
|
||||
// base case 退出提交
|
||||
if(head == null || head.next == null) return head;
|
||||
// 获取当前节点的下一个节点
|
||||
ListNode next = head.next;
|
||||
// 进行递归
|
||||
ListNode newNode = swapPairs(next.next);
|
||||
// 这里进行交换
|
||||
next.next = head;
|
||||
head.next = newNode;
|
||||
|
||||
return next;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
// 虚拟头结点
|
||||
class Solution {
|
||||
public ListNode swapPairs(ListNode head) {
|
||||
|
||||
ListNode dummyNode = new ListNode(0);
|
||||
dummyNode.next = head;
|
||||
ListNode prev = dummyNode;
|
||||
|
||||
while (prev.next != null && prev.next.next != null) {
|
||||
ListNode temp = head.next.next; // 缓存 next
|
||||
prev.next = head.next; // 将 prev 的 next 改为 head 的 next
|
||||
head.next.next = head; // 将 head.next(prev.next) 的next,指向 head
|
||||
head.next = temp; // 将head 的 next 接上缓存的temp
|
||||
prev = head; // 步进1位
|
||||
head = head.next; // 步进1位
|
||||
}
|
||||
return dummyNode.next;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
Go:
|
||||
|
||||
|
||||
-----------------------
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -123,15 +123,68 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```java
|
||||
class Solution {
|
||||
public int removeElement(int[] nums, int val) {
|
||||
|
||||
// 快慢指针
|
||||
int fastIndex = 0;
|
||||
int slowIndex;
|
||||
for (slowIndex = 0; fastIndex < nums.length; fastIndex++) {
|
||||
if (nums[fastIndex] != val) {
|
||||
nums[slowIndex] = nums[fastIndex];
|
||||
slowIndex++;
|
||||
}
|
||||
}
|
||||
return slowIndex;
|
||||
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def removeElement(self, nums: List[int], val: int) -> int:
|
||||
i,n = 0,len(nums)
|
||||
for j in range(n):
|
||||
if nums[j] != val:
|
||||
nums[i] = nums[j]
|
||||
i += 1
|
||||
return i
|
||||
```
|
||||
|
||||
|
||||
Go:
|
||||
```go
|
||||
func removeElement(nums []int, val int) int {
|
||||
length:=len(nums)
|
||||
res:=0
|
||||
for i:=0;i<length;i++{
|
||||
if nums[i]!=val {
|
||||
nums[res]=nums[i]
|
||||
res++
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
JavaScript:
|
||||
```
|
||||
//时间复杂度O(n)
|
||||
//空间复杂度O(1)
|
||||
var removeElement = (nums, val) => {
|
||||
let k = 0;
|
||||
for(let i = 0;i < nums.length;i++){
|
||||
if(nums[i] != val){
|
||||
nums[k++] = nums[i]
|
||||
}
|
||||
}
|
||||
return k;
|
||||
};
|
||||
```
|
||||
|
||||
-----------------------
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
|
@ -565,6 +565,54 @@ public:
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
/**
|
||||
* 基于窗口滑动的算法
|
||||
* <p>
|
||||
* 时间复杂度:O(m*n)
|
||||
* 空间复杂度:O(1)
|
||||
* 注:n为haystack的长度,m为needle的长度
|
||||
*/
|
||||
public int strStr(String haystack, String needle) {
|
||||
int m = needle.length();
|
||||
// 当 needle 是空字符串时我们应当返回 0
|
||||
if (m == 0) {
|
||||
return 0;
|
||||
}
|
||||
int n = haystack.length();
|
||||
if (n < m) {
|
||||
return -1;
|
||||
}
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
while (i < n - m + 1) {
|
||||
// 找到首字母相等
|
||||
while (i < n && haystack.charAt(i) != needle.charAt(j)) {
|
||||
i++;
|
||||
}
|
||||
if (i == n) {// 没有首字母相等的
|
||||
return -1;
|
||||
}
|
||||
// 遍历后续字符,判断是否相等
|
||||
i++;
|
||||
j++;
|
||||
while (i < n && j < m && haystack.charAt(i) == needle.charAt(j)) {
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
if (j == m) {// 找到
|
||||
return i - j;
|
||||
} else {// 未找到
|
||||
i -= j - 1;
|
||||
j = 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
// 方法一
|
||||
class Solution {
|
||||
|
@ -205,11 +205,54 @@ public:
|
||||
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public int searchInsert(int[] nums, int target) {
|
||||
int n = nums.length;
|
||||
|
||||
// 定义target在左闭右闭的区间,[low, high]
|
||||
int low = 0;
|
||||
int high = n - 1;
|
||||
|
||||
while (low <= high) { // 当low==high,区间[low, high]依然有效
|
||||
int mid = low + (high - low) / 2; // 防止溢出
|
||||
if (nums[mid] > target) {
|
||||
high = mid - 1; // target 在左区间,所以[low, mid - 1]
|
||||
} else if (nums[mid] < target) {
|
||||
low = mid + 1; // target 在右区间,所以[mid + 1, high]
|
||||
} else {
|
||||
// 1. 目标值等于数组中某一个元素 return mid;
|
||||
return mid;
|
||||
}
|
||||
}
|
||||
// 2.目标值在数组所有元素之前 3.目标值插入数组中 4.目标值在数组所有元素之后 return right + 1;
|
||||
return high + 1;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
Python:
|
||||
```python3
|
||||
class Solution:
|
||||
def searchInsert(self, nums: List[int], target: int) -> int:
|
||||
left, right = 0, len(nums) - 1
|
||||
|
||||
while left <= right:
|
||||
middle = (left + right) // 2
|
||||
|
||||
if nums[middle] < target:
|
||||
left = middle + 1
|
||||
elif nums[middle] > target:
|
||||
right = middle - 1
|
||||
else:
|
||||
return middle
|
||||
return right + 1
|
||||
```
|
||||
|
||||
|
||||
Go:
|
||||
|
@ -219,7 +219,72 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```java
|
||||
class Solution {
|
||||
public void solveSudoku(char[][] board) {
|
||||
solveSudokuHelper(board);
|
||||
}
|
||||
|
||||
private boolean solveSudokuHelper(char[][] board){
|
||||
//「一个for循环遍历棋盘的行,一个for循环遍历棋盘的列,
|
||||
// 一行一列确定下来之后,递归遍历这个位置放9个数字的可能性!」
|
||||
for (int i = 0; i < 9; i++){ // 遍历行
|
||||
for (int j = 0; j < 9; j++){ // 遍历列
|
||||
if (board[i][j] != '.'){ // 跳过原始数字
|
||||
continue;
|
||||
}
|
||||
for (char k = '1'; k <= '9'; k++){ // (i, j) 这个位置放k是否合适
|
||||
if (isValidSudoku(i, j, k, board)){
|
||||
board[i][j] = k;
|
||||
if (solveSudokuHelper(board)){ // 如果找到合适一组立刻返回
|
||||
return true;
|
||||
}
|
||||
board[i][j] = '.';
|
||||
}
|
||||
}
|
||||
// 9个数都试完了,都不行,那么就返回false
|
||||
return false;
|
||||
// 因为如果一行一列确定下来了,这里尝试了9个数都不行,说明这个棋盘找不到解决数独问题的解!
|
||||
// 那么会直接返回, 「这也就是为什么没有终止条件也不会永远填不满棋盘而无限递归下去!」
|
||||
}
|
||||
}
|
||||
// 遍历完没有返回false,说明找到了合适棋盘位置了
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断棋盘是否合法有如下三个维度:
|
||||
* 同行是否重复
|
||||
* 同列是否重复
|
||||
* 9宫格里是否重复
|
||||
*/
|
||||
private boolean isValidSudoku(int row, int col, char val, char[][] board){
|
||||
// 同行是否重复
|
||||
for (int i = 0; i < 9; i++){
|
||||
if (board[row][i] == val){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// 同列是否重复
|
||||
for (int j = 0; j < 9; j++){
|
||||
if (board[j][col] == val){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// 9宫格里是否重复
|
||||
int startRow = (row / 3) * 3;
|
||||
int startCol = (col / 3) * 3;
|
||||
for (int i = startRow; i < startRow + 3; i++){
|
||||
for (int j = startCol; j < startCol + 3; j++){
|
||||
if (board[i][j] == val){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
@ -236,7 +236,39 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```Java
|
||||
class Solution {
|
||||
List<List<Integer>> lists = new ArrayList<>();
|
||||
Deque<Integer> deque = new LinkedList<>();
|
||||
|
||||
public List<List<Integer>> combinationSum3(int k, int n) {
|
||||
int[] arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
backTracking(arr, n, k, 0);
|
||||
return lists;
|
||||
}
|
||||
|
||||
public void backTracking(int[] arr, int n, int k, int startIndex) {
|
||||
//如果 n 小于0,没必要继续本次递归,已经不符合要求了
|
||||
if (n < 0) {
|
||||
return;
|
||||
}
|
||||
if (deque.size() == k) {
|
||||
if (n == 0) {
|
||||
lists.add(new ArrayList(deque));
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (int i = startIndex; i < arr.length - (k - deque.size()) + 1; i++) {
|
||||
deque.push(arr[i]);
|
||||
//减去当前元素
|
||||
n -= arr[i];
|
||||
backTracking(arr, n, k, i + 1);
|
||||
//恢复n
|
||||
n += deque.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
@ -255,7 +255,43 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```Java
|
||||
class Solution {
|
||||
List<List<Integer>> lists = new ArrayList<>();
|
||||
Deque<Integer> deque = new LinkedList<>();
|
||||
int sum = 0;
|
||||
|
||||
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
|
||||
//为了将重复的数字都放到一起,所以先进行排序
|
||||
Arrays.sort(candidates);
|
||||
//加标志数组,用来辅助判断同层节点是否已经遍历
|
||||
boolean[] flag = new boolean[candidates.length];
|
||||
backTracking(candidates, target, 0, flag);
|
||||
return lists;
|
||||
}
|
||||
|
||||
public void backTracking(int[] arr, int target, int index, boolean[] flag) {
|
||||
if (sum == target) {
|
||||
lists.add(new ArrayList(deque));
|
||||
return;
|
||||
}
|
||||
for (int i = index; i < arr.length && arr[i] + sum <= target; i++) {
|
||||
//出现重复节点,同层的第一个节点已经被访问过,所以直接跳过
|
||||
if (i > 0 && arr[i] == arr[i - 1] && !flag[i - 1]) {
|
||||
continue;
|
||||
}
|
||||
flag[i] = true;
|
||||
sum += arr[i];
|
||||
deque.push(arr[i]);
|
||||
//每个节点仅能选择一次,所以从下一位开始
|
||||
backTracking(arr, target, i + 1, flag);
|
||||
int temp = deque.pop();
|
||||
flag[i] = false;
|
||||
sum -= temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
@ -143,10 +143,54 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
public int jump(int[] nums) {
|
||||
if (nums == null || nums.length == 0 || nums.length == 1) {
|
||||
return 0;
|
||||
}
|
||||
//记录跳跃的次数
|
||||
int count=0;
|
||||
//当前的覆盖最大区域
|
||||
int curDistance = 0;
|
||||
//最大的覆盖区域
|
||||
int maxDistance = 0;
|
||||
for (int i = 0; i < nums.length; i++) {
|
||||
//在可覆盖区域内更新最大的覆盖区域
|
||||
maxDistance = Math.max(maxDistance,i+nums[i]);
|
||||
//说明当前一步,再跳一步就到达了末尾
|
||||
if (maxDistance>=nums.length-1){
|
||||
count++;
|
||||
break;
|
||||
}
|
||||
//走到当前覆盖的最大区域时,更新下一步可达的最大区域
|
||||
if (i==curDistance){
|
||||
curDistance = maxDistance;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def jump(self, nums: List[int]) -> int:
|
||||
if len(nums) == 1: return 0
|
||||
ans = 0
|
||||
curDistance = 0
|
||||
nextDistance = 0
|
||||
for i in range(len(nums)):
|
||||
nextDistance = max(i + nums[i], nextDistance)
|
||||
if i == curDistance:
|
||||
if curDistance != len(nums) - 1:
|
||||
ans += 1
|
||||
curDistance = nextDistance
|
||||
if nextDistance >= len(nums) - 1: break
|
||||
return ans
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
|
@ -147,13 +147,74 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```java
|
||||
class Solution {
|
||||
|
||||
List<List<Integer>> result = new ArrayList<>();// 存放符合条件结果的集合
|
||||
LinkedList<Integer> path = new LinkedList<>();// 用来存放符合条件结果
|
||||
boolean[] used;
|
||||
public List<List<Integer>> permute(int[] nums) {
|
||||
if (nums.length == 0){
|
||||
return result;
|
||||
}
|
||||
used = new boolean[nums.length];
|
||||
permuteHelper(nums);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void permuteHelper(int[] nums){
|
||||
if (path.size() == nums.length){
|
||||
result.add(new ArrayList<>(path));
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < nums.length; i++){
|
||||
if (used[i]){
|
||||
continue;
|
||||
}
|
||||
used[i] = true;
|
||||
path.add(nums[i]);
|
||||
permuteHelper(nums);
|
||||
path.removeLast();
|
||||
used[i] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
Go:
|
||||
```Go
|
||||
var result [][]int
|
||||
func backtrack(nums,pathNums []int,used []bool){
|
||||
if len(nums)==len(pathNums){
|
||||
tmp:=make([]int,len(nums))
|
||||
copy(tmp,pathNums)
|
||||
result=append(result,tmp)
|
||||
//result=append(result,pathNums)
|
||||
return
|
||||
}
|
||||
for i:=0;i<len(nums);i++{
|
||||
if !used[i]{
|
||||
used[i]=true
|
||||
pathNums=append(pathNums,nums[i])
|
||||
backtrack(nums,pathNums,used)
|
||||
pathNums=pathNums[:len(pathNums)-1]
|
||||
used[i]=false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func permute(nums []int) [][]int {
|
||||
//var pathNums []int
|
||||
pathNums:=make([]int,0)
|
||||
var used=make([]bool,len(nums))
|
||||
result=[][]int{}
|
||||
backtrack(nums,pathNums,used)
|
||||
return result
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
@ -85,7 +85,7 @@ public:
|
||||
path.clear();
|
||||
sort(nums.begin(), nums.end()); // 排序
|
||||
vector<bool> used(nums.size(), false);
|
||||
backtracking(nums, vec, used);
|
||||
backtracking(nums, used);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
@ -363,7 +363,72 @@ Python:
|
||||
|
||||
|
||||
Go:
|
||||
```Go
|
||||
import "strings"
|
||||
var res [][]string
|
||||
|
||||
func isValid(board [][]string, row, col int) (res bool){
|
||||
n := len(board)
|
||||
for i:=0; i < row; i++ {
|
||||
if board[i][col] == "Q" {
|
||||
return false
|
||||
}
|
||||
}
|
||||
for i := 0; i < n; i++{
|
||||
if board[row][i] == "Q" {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
for i ,j := row, col; i >= 0 && j >=0 ; i, j = i - 1, j- 1{
|
||||
if board[i][j] == "Q"{
|
||||
return false
|
||||
}
|
||||
}
|
||||
for i, j := row, col; i >=0 && j < n; i,j = i-1, j+1 {
|
||||
if board[i][j] == "Q" {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func backtrack(board [][]string, row int) {
|
||||
size := len(board)
|
||||
if row == size{
|
||||
temp := make([]string, size)
|
||||
for i := 0; i<size;i++{
|
||||
temp[i] = strings.Join(board[i],"")
|
||||
}
|
||||
res =append(res,temp)
|
||||
return
|
||||
}
|
||||
for col := 0; col < size; col++ {
|
||||
if !isValid(board, row, col){
|
||||
continue
|
||||
}
|
||||
board[row][col] = "Q"
|
||||
backtrack(board, row+1)
|
||||
board[row][col] = "."
|
||||
}
|
||||
}
|
||||
|
||||
func solveNQueens(n int) [][]string {
|
||||
res = [][]string{}
|
||||
board := make([][]string, n)
|
||||
for i := 0; i < n; i++{
|
||||
board[i] = make([]string, n)
|
||||
}
|
||||
for i := 0; i < n; i++{
|
||||
for j := 0; j<n;j++{
|
||||
board[i][j] = "."
|
||||
}
|
||||
}
|
||||
backtrack(board, 0)
|
||||
|
||||
return res
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
@ -139,12 +139,43 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public int maxSubArray(int[] nums) {
|
||||
if (nums.length == 1){
|
||||
return nums[0];
|
||||
}
|
||||
int sum = Integer.MIN_VALUE;
|
||||
int count = 0;
|
||||
for (int i = 0; i < nums.length; i++){
|
||||
count += nums[i];
|
||||
sum = Math.max(sum, count); // 取区间累计的最大值(相当于不断确定最大子序终止位置)
|
||||
if (count <= 0){
|
||||
count = 0; // 相当于重置最大子序起始位置,因为遇到负数一定是拉低总和
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def maxSubArray(self, nums: List[int]) -> int:
|
||||
result = -float('inf')
|
||||
count = 0
|
||||
for i in range(len(nums)):
|
||||
count += nums[i]
|
||||
if count > result:
|
||||
result = count
|
||||
if count <= 0:
|
||||
count = 0
|
||||
return result
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
```go
|
||||
func maxSubArray(nums []int) int {
|
||||
maxSum := nums[0]
|
||||
@ -162,6 +193,7 @@ func maxSubArray(nums []int) int {
|
||||
|
||||
|
||||
|
||||
|
||||
-----------------------
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
|
@ -86,10 +86,40 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
public boolean canJump(int[] nums) {
|
||||
if (nums.length == 1) {
|
||||
return true;
|
||||
}
|
||||
//覆盖范围
|
||||
int coverRange = nums[0];
|
||||
//在覆盖范围内更新最大的覆盖范围
|
||||
for (int i = 0; i <= coverRange; i++) {
|
||||
coverRange = Math.max(coverRange, i + nums[i]);
|
||||
if (coverRange >= nums.length - 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def canJump(self, nums: List[int]) -> bool:
|
||||
cover = 0
|
||||
if len(nums) == 1: return True
|
||||
i = 0
|
||||
# python不支持动态修改for循环中变量,使用while循环代替
|
||||
while i <= cover:
|
||||
cover = max(i + nums[i], cover)
|
||||
if cover >= len(nums) - 1: return True
|
||||
i += 1
|
||||
return False
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
|
@ -137,7 +137,35 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```java
|
||||
class Solution {
|
||||
public int[][] merge(int[][] intervals) {
|
||||
List<int[]> res = new LinkedList<>();
|
||||
Arrays.sort(intervals, new Comparator<int[]>() {
|
||||
@Override
|
||||
public int compare(int[] o1, int[] o2) {
|
||||
if (o1[0] != o2[0]) {
|
||||
return Integer.compare(o1[0],o2[0]);
|
||||
} else {
|
||||
return Integer.compare(o1[1],o2[1]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
int start = intervals[0][0];
|
||||
for (int i = 1; i < intervals.length; i++) {
|
||||
if (intervals[i][0] > intervals[i - 1][1]) {
|
||||
res.add(new int[]{start, intervals[i - 1][1]});
|
||||
start = intervals[i][0];
|
||||
} else {
|
||||
intervals[i][1] = Math.max(intervals[i][1], intervals[i - 1][1]);
|
||||
}
|
||||
}
|
||||
res.add(new int[]{start, intervals[intervals.length - 1][1]});
|
||||
return res.toArray(new int[res.size()][]);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
@ -151,4 +179,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -212,7 +212,45 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```Java
|
||||
class Solution {
|
||||
public int climbStairs(int n) {
|
||||
// 跟斐波那契数列一样
|
||||
if(n <= 2) return n;
|
||||
int a = 1, b = 2, sum = 0;
|
||||
|
||||
for(int i = 3; i <= n; i++){
|
||||
sum = a + b;
|
||||
a = b;
|
||||
b = sum;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
// 常规方式
|
||||
public int climbStairs(int n) {
|
||||
int[] dp = new int[n + 1];
|
||||
dp[0] = 1;
|
||||
dp[1] = 1;
|
||||
for (int i = 2; i <= n; i++) {
|
||||
dp[i] = dp[i - 1] + dp[i - 2];
|
||||
}
|
||||
return dp[n];
|
||||
}
|
||||
// 用变量记录代替数组
|
||||
public int climbStairs(int n) {
|
||||
int a = 0, b = 1, c = 0; // 默认需要1次
|
||||
for (int i = 1; i <= n; i++) {
|
||||
c = a + b; // f(i - 1) + f(n - 2)
|
||||
a = b; // 记录上一轮的值
|
||||
b = c; // 向后步进1个数
|
||||
}
|
||||
return c;
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
@ -230,7 +268,20 @@ class Solution:
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
```Go
|
||||
func climbStairs(n int) int {
|
||||
if n==1{
|
||||
return 1
|
||||
}
|
||||
dp:=make([]int,n+1)
|
||||
dp[1]=1
|
||||
dp[2]=2
|
||||
for i:=3;i<=n;i++{
|
||||
dp[i]=dp[i-1]+dp[i-2]
|
||||
}
|
||||
return dp[n]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
@ -127,7 +127,23 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```java
|
||||
class Solution {
|
||||
public int climbStairs(int n) {
|
||||
int[] dp = new int[n + 1];
|
||||
int[] weight = {1,2};
|
||||
dp[0] = 1;
|
||||
|
||||
for (int i = 0; i <= n; i++) {
|
||||
for (int j = 0; j < weight.length; j++) {
|
||||
if (i >= weight[j]) dp[i] += dp[i - weight[j]];
|
||||
}
|
||||
}
|
||||
|
||||
return dp[n];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
@ -141,4 +157,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -198,13 +198,71 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```java
|
||||
public int minDistance(String word1, String word2) {
|
||||
int m = word1.length();
|
||||
int n = word2.length();
|
||||
int[][] dp = new int[m + 1][n + 1];
|
||||
// 初始化
|
||||
for (int i = 1; i <= m; i++) {
|
||||
dp[i][0] = i;
|
||||
}
|
||||
for (int j = 1; j <= n; j++) {
|
||||
dp[0][j] = j;
|
||||
}
|
||||
for (int i = 1; i <= m; i++) {
|
||||
for (int j = 1; j <= n; j++) {
|
||||
// 因为dp数组有效位从1开始
|
||||
// 所以当前遍历到的字符串的位置为i-1 | j-1
|
||||
if (word1.charAt(i - 1) == word2.charAt(j - 1)) {
|
||||
dp[i][j] = dp[i - 1][j - 1];
|
||||
} else {
|
||||
dp[i][j] = Math.min(Math.min(dp[i - 1][j - 1], dp[i][j - 1]), dp[i - 1][j]) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[m][n];
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
Go:
|
||||
|
||||
```Go
|
||||
func minDistance(word1 string, word2 string) int {
|
||||
m, n := len(word1), len(word2)
|
||||
dp := make([][]int, m+1)
|
||||
for i := range dp {
|
||||
dp[i] = make([]int, n+1)
|
||||
}
|
||||
for i := 0; i < m+1; i++ {
|
||||
dp[i][0] = i // word1[i] 变成 word2[0], 删掉 word1[i], 需要 i 部操作
|
||||
}
|
||||
for j := 0; j < n+1; j++ {
|
||||
dp[0][j] = j // word1[0] 变成 word2[j], 插入 word1[j],需要 j 部操作
|
||||
}
|
||||
for i := 1; i < m+1; i++ {
|
||||
for j := 1; j < n+1; j++ {
|
||||
if word1[i-1] == word2[j-1] {
|
||||
dp[i][j] = dp[i-1][j-1]
|
||||
} else { // Min(插入,删除,替换)
|
||||
dp[i][j] = Min(dp[i][j-1], dp[i-1][j], dp[i-1][j-1]) + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[m][n]
|
||||
}
|
||||
func Min(args ...int) int {
|
||||
min := args[0]
|
||||
for _, item := range args {
|
||||
if item < min {
|
||||
min = item
|
||||
}
|
||||
}
|
||||
return min
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
@ -340,12 +340,65 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```java
|
||||
class Solution {
|
||||
List<List<Integer>> result = new ArrayList<>();
|
||||
LinkedList<Integer> path = new LinkedList<>();
|
||||
public List<List<Integer>> combine(int n, int k) {
|
||||
combineHelper(n, k, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 每次从集合中选取元素,可选择的范围随着选择的进行而收缩,调整可选择的范围,就是要靠startIndex
|
||||
* @param startIndex 用来记录本层递归的中,集合从哪里开始遍历(集合就是[1,...,n] )。
|
||||
*/
|
||||
private void combineHelper(int n, int k, int startIndex){
|
||||
//终止条件
|
||||
if (path.size() == k){
|
||||
result.add(new ArrayList<>(path));
|
||||
return;
|
||||
}
|
||||
for (int i = startIndex; i <= n - (k - path.size()) + 1; i++){
|
||||
path.add(i);
|
||||
combineHelper(n, k, i + 1);
|
||||
path.removeLast();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
Go:
|
||||
```Go
|
||||
var res [][]int
|
||||
func combine(n int, k int) [][]int {
|
||||
res=[][]int{}
|
||||
if n <= 0 || k <= 0 || k > n {
|
||||
return res
|
||||
}
|
||||
backtrack(n, k, 1, []int{})
|
||||
return res
|
||||
}
|
||||
func backtrack(n,k,start int,track []int){
|
||||
if len(track)==k{
|
||||
temp:=make([]int,k)
|
||||
copy(temp,track)
|
||||
res=append(res,temp)
|
||||
}
|
||||
if len(track)+n-start+1 < k {
|
||||
return
|
||||
}
|
||||
for i:=start;i<=n;i++{
|
||||
track=append(track,i)
|
||||
backtrack(n,k,i+1,track)
|
||||
track=track[:len(track)-1]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
@ -147,7 +147,33 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```
|
||||
class Solution {
|
||||
List<List<Integer>> result = new ArrayList<>();
|
||||
LinkedList<Integer> path = new LinkedList<>();
|
||||
public List<List<Integer>> combine(int n, int k) {
|
||||
combineHelper(n, k, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 每次从集合中选取元素,可选择的范围随着选择的进行而收缩,调整可选择的范围,就是要靠startIndex
|
||||
* @param startIndex 用来记录本层递归的中,集合从哪里开始遍历(集合就是[1,...,n] )。
|
||||
*/
|
||||
private void combineHelper(int n, int k, int startIndex){
|
||||
//终止条件
|
||||
if (path.size() == k){
|
||||
result.add(new ArrayList<>(path));
|
||||
return;
|
||||
}
|
||||
for (int i = startIndex; i <= n - (k - path.size()) + 1; i++){
|
||||
path.add(i);
|
||||
combineHelper(n, k, i + 1);
|
||||
path.removeLast();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
@ -177,14 +177,79 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```java
|
||||
class Solution {
|
||||
List<List<Integer>> result = new ArrayList<>();// 存放符合条件结果的集合
|
||||
LinkedList<Integer> path = new LinkedList<>();// 用来存放符合条件结果
|
||||
public List<List<Integer>> subsets(int[] nums) {
|
||||
if (nums.length == 0){
|
||||
result.add(new ArrayList<>());
|
||||
return result;
|
||||
}
|
||||
Arrays.sort(nums);
|
||||
subsetsHelper(nums, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void subsetsHelper(int[] nums, int startIndex){
|
||||
result.add(new ArrayList<>(path));//「遍历这个树的时候,把所有节点都记录下来,就是要求的子集集合」。
|
||||
if (startIndex >= nums.length){ //终止条件可不加
|
||||
return;
|
||||
}
|
||||
for (int i = startIndex; i < nums.length; i++){
|
||||
path.add(nums[i]);
|
||||
subsetsHelper(nums, i + 1);
|
||||
path.removeLast();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
Go:
|
||||
```Go
|
||||
var res [][]int
|
||||
func subset(nums []int) [][]int {
|
||||
res = make([][]int, 0)
|
||||
sort.Ints(nums)
|
||||
Dfs([]int{}, nums, 0)
|
||||
return res
|
||||
}
|
||||
func Dfs(temp, nums []int, start int){
|
||||
tmp := make([]int, len(temp))
|
||||
copy(tmp, temp)
|
||||
res = append(res, tmp)
|
||||
for i := start; i < len(nums); i++{
|
||||
//if i>start&&nums[i]==nums[i-1]{
|
||||
// continue
|
||||
//}
|
||||
temp = append(temp, nums[i])
|
||||
Dfs(temp, nums, i+1)
|
||||
temp = temp[:len(temp)-1]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Javascript:
|
||||
|
||||
```Javascript
|
||||
var subsets = function(nums) {
|
||||
let result = []
|
||||
let path = []
|
||||
function backtracking(startIndex) {
|
||||
result.push(path.slice())
|
||||
for(let i = startIndex; i < nums.length; i++) {
|
||||
path.push(nums[i])
|
||||
backtracking(i + 1)
|
||||
path.pop()
|
||||
}
|
||||
}
|
||||
backtracking(0)
|
||||
return result
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
@ -172,13 +172,99 @@ if (i > startIndex && nums[i] == nums[i - 1] ) {
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
List<List<Integer>> result = new ArrayList<>();// 存放符合条件结果的集合
|
||||
LinkedList<Integer> path = new LinkedList<>();// 用来存放符合条件结果
|
||||
boolean[] used;
|
||||
public List<List<Integer>> subsetsWithDup(int[] nums) {
|
||||
if (nums.length == 0){
|
||||
result.add(path);
|
||||
return result;
|
||||
}
|
||||
Arrays.sort(nums);
|
||||
used = new boolean[nums.length];
|
||||
subsetsWithDupHelper(nums, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void subsetsWithDupHelper(int[] nums, int startIndex){
|
||||
result.add(new ArrayList<>(path));
|
||||
if (startIndex >= nums.length){
|
||||
return;
|
||||
}
|
||||
for (int i = startIndex; i < nums.length; i++){
|
||||
if (i > 0 && nums[i] == nums[i - 1] && !used[i - 1]){
|
||||
continue;
|
||||
}
|
||||
path.add(nums[i]);
|
||||
used[i] = true;
|
||||
subsetsWithDupHelper(nums, i + 1);
|
||||
path.removeLast();
|
||||
used[i] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
Go:
|
||||
```Go
|
||||
var res[][]int
|
||||
func subsetsWithDup(nums []int)[][]int {
|
||||
res=make([][]int,0)
|
||||
sort.Ints(nums)
|
||||
dfs([]int{},nums,0)
|
||||
return res
|
||||
}
|
||||
func dfs(temp, num []int, start int) {
|
||||
tmp:=make([]int,len(temp))
|
||||
copy(tmp,temp)
|
||||
|
||||
res=append(res,tmp)
|
||||
for i:=start;i<len(num);i++{
|
||||
if i>start&&num[i]==num[i-1]{
|
||||
continue
|
||||
}
|
||||
temp=append(temp,num[i])
|
||||
dfs(temp,num,i+1)
|
||||
temp=temp[:len(temp)-1]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Javascript:
|
||||
|
||||
```Javascript
|
||||
|
||||
var subsetsWithDup = function(nums) {
|
||||
let result = []
|
||||
let path = []
|
||||
let sortNums = nums.sort((a, b) => {
|
||||
return a - b
|
||||
})
|
||||
function backtracing(startIndex, sortNums) {
|
||||
result.push(path.slice(0))
|
||||
if(startIndex > nums.length - 1) {
|
||||
return
|
||||
}
|
||||
for(let i = startIndex; i < nums.length; i++) {
|
||||
if(i > startIndex && nums[i] === nums[i - 1]) {
|
||||
continue
|
||||
}
|
||||
path.push(nums[i])
|
||||
backtracing(i + 1, sortNums)
|
||||
path.pop()
|
||||
}
|
||||
}
|
||||
backtracing(0, sortNums)
|
||||
return result
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
@ -165,13 +165,42 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
public int numTrees(int n) {
|
||||
//初始化 dp 数组
|
||||
int[] dp = new int[n + 1];
|
||||
//初始化0个节点和1个节点的情况
|
||||
dp[0] = 1;
|
||||
dp[1] = 1;
|
||||
for (int i = 2; i <= n; i++) {
|
||||
for (int j = 1; j <= i; j++) {
|
||||
//对于第i个节点,需要考虑1作为根节点直到i作为根节点的情况,所以需要累加
|
||||
//一共i个节点,对于根节点j时,左子树的节点个数为j-1,右子树的节点个数为i-j
|
||||
dp[i] += dp[j - 1] * dp[i - j];
|
||||
}
|
||||
}
|
||||
return dp[n];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
Go:
|
||||
|
||||
```Go
|
||||
func numTrees(n int)int{
|
||||
dp:=make([]int,n+1)
|
||||
dp[0]=1
|
||||
for i:=1;i<=n;i++{
|
||||
for j:=1;j<=i;j++{
|
||||
dp[i]+=dp[j-1]*dp[i-j]
|
||||
}
|
||||
}
|
||||
return dp[n]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
@ -255,12 +255,109 @@ public:
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
// 递归
|
||||
TreeNode max;
|
||||
public boolean isValidBST(TreeNode root) {
|
||||
if (root == null) {
|
||||
return true;
|
||||
}
|
||||
// 左
|
||||
boolean left = isValidBST(root.left);
|
||||
if (!left) {
|
||||
return false;
|
||||
}
|
||||
// 中
|
||||
if (max != null && root.val <= max.val) {
|
||||
return false;
|
||||
}
|
||||
max = root;
|
||||
// 右
|
||||
boolean right = isValidBST(root.right);
|
||||
return right;
|
||||
}
|
||||
}
|
||||
|
||||
class Solution {
|
||||
// 迭代
|
||||
public boolean isValidBST(TreeNode root) {
|
||||
if (root == null) {
|
||||
return true;
|
||||
}
|
||||
Stack<TreeNode> stack = new Stack<>();
|
||||
TreeNode pre = null;
|
||||
while (root != null || !stack.isEmpty()) {
|
||||
while (root != null) {
|
||||
stack.push(root);
|
||||
root = root.left;// 左
|
||||
}
|
||||
// 中,处理
|
||||
TreeNode pop = stack.pop();
|
||||
if (pre != null && pop.val <= pre.val) {
|
||||
return false;
|
||||
}
|
||||
pre = pop;
|
||||
|
||||
root = pop.right;// 右
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// 简洁实现·递归解法
|
||||
class Solution {
|
||||
public boolean isValidBST(TreeNode root) {
|
||||
return validBST(Long.MIN_VALUE, Long.MAX_VALUE, root);
|
||||
}
|
||||
boolean validBST(long lower, long upper, TreeNode root) {
|
||||
if (root == null) return true;
|
||||
if (root.val <= lower || root.val >= upper) return false;
|
||||
return validBST(lower, root.val, root.left) && validBST(root.val, upper, root.right);
|
||||
}
|
||||
}
|
||||
// 简洁实现·中序遍历
|
||||
class Solution {
|
||||
private long prev = Long.MIN_VALUE;
|
||||
public boolean isValidBST(TreeNode root) {
|
||||
if (root == null) {
|
||||
return true;
|
||||
}
|
||||
if (!isValidBST(root.left)) {
|
||||
return false;
|
||||
}
|
||||
if (root.val <= prev) { // 不满足二叉搜索树条件
|
||||
return false;
|
||||
}
|
||||
prev = root.val;
|
||||
return isValidBST(root.right);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
Go:
|
||||
```Go
|
||||
import "math"
|
||||
|
||||
func isValidBST(root *TreeNode) bool {
|
||||
if root == nil {
|
||||
return true
|
||||
}
|
||||
return isBST(root, math.MinInt64, math.MaxFloat64)
|
||||
}
|
||||
func isBST(root *TreeNode, min, max int) bool {
|
||||
if root == nil {
|
||||
return true
|
||||
}
|
||||
if min >= root.Val || max <= root.Val {
|
||||
return false
|
||||
}
|
||||
return isBST(root.Left, min, root.Val) && isBST(root.Right, root.Val, max)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
@ -268,4 +365,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -253,9 +253,110 @@ public:
|
||||
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
/**
|
||||
* 递归法
|
||||
*/
|
||||
public boolean isSymmetric1(TreeNode root) {
|
||||
return compare(root.left, root.right);
|
||||
}
|
||||
|
||||
private boolean compare(TreeNode left, TreeNode right) {
|
||||
|
||||
if (left == null && right != null) {
|
||||
return false;
|
||||
}
|
||||
if (left != null && right == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (left == null && right == null) {
|
||||
return true;
|
||||
}
|
||||
if (left.val != right.val) {
|
||||
return false;
|
||||
}
|
||||
// 比较外侧
|
||||
boolean compareOutside = compare(left.left, right.right);
|
||||
// 比较内侧
|
||||
boolean compareInside = compare(left.right, right.left);
|
||||
return compareOutside && compareInside;
|
||||
}
|
||||
|
||||
/**
|
||||
* 迭代法
|
||||
* 使用双端队列,相当于两个栈
|
||||
*/
|
||||
public boolean isSymmetric2(TreeNode root) {
|
||||
Deque<TreeNode> deque = new LinkedList<>();
|
||||
deque.offerFirst(root.left);
|
||||
deque.offerLast(root.right);
|
||||
while (!deque.isEmpty()) {
|
||||
TreeNode leftNode = deque.pollFirst();
|
||||
TreeNode rightNode = deque.pollLast();
|
||||
if (leftNode == null && rightNode == null) {
|
||||
continue;
|
||||
}
|
||||
// if (leftNode == null && rightNode != null) {
|
||||
// return false;
|
||||
// }
|
||||
// if (leftNode != null && rightNode == null) {
|
||||
// return false;
|
||||
// }
|
||||
// if (leftNode.val != rightNode.val) {
|
||||
// return false;
|
||||
// }
|
||||
// 以上三个判断条件合并
|
||||
if (leftNode == null || rightNode == null || leftNode.val != rightNode.val) {
|
||||
return false;
|
||||
}
|
||||
deque.offerFirst(leftNode.left);
|
||||
deque.offerFirst(leftNode.right);
|
||||
deque.offerLast(rightNode.right);
|
||||
deque.offerLast(rightNode.left);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 迭代法
|
||||
* 使用普通队列
|
||||
*/
|
||||
public boolean isSymmetric3(TreeNode root) {
|
||||
Queue<TreeNode> deque = new LinkedList<>();
|
||||
deque.offer(root.left);
|
||||
deque.offer(root.right);
|
||||
while (!deque.isEmpty()) {
|
||||
TreeNode leftNode = deque.poll();
|
||||
TreeNode rightNode = deque.poll();
|
||||
if (leftNode == null && rightNode == null) {
|
||||
continue;
|
||||
}
|
||||
// if (leftNode == null && rightNode != null) {
|
||||
// return false;
|
||||
// }
|
||||
// if (leftNode != null && rightNode == null) {
|
||||
// return false;
|
||||
// }
|
||||
// if (leftNode.val != rightNode.val) {
|
||||
// return false;
|
||||
// }
|
||||
// 以上三个判断条件合并
|
||||
if (leftNode == null || rightNode == null || leftNode.val != rightNode.val) {
|
||||
return false;
|
||||
}
|
||||
// 这里顺序与使用Deque不同
|
||||
deque.offer(leftNode.left);
|
||||
deque.offer(rightNode.right);
|
||||
deque.offer(leftNode.right);
|
||||
deque.offer(rightNode.left);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
@ -263,6 +364,21 @@ Python:
|
||||
Go:
|
||||
|
||||
|
||||
JavaScript
|
||||
```javascript
|
||||
var isSymmetric = function(root) {
|
||||
return check(root, root)
|
||||
};
|
||||
|
||||
const check = (leftPtr, rightPtr) => {
|
||||
// 如果只有根节点,返回true
|
||||
if (!leftPtr && !rightPtr) return true
|
||||
// 如果左右节点只存在一个,则返回false
|
||||
if (!leftPtr || !rightPtr) return false
|
||||
|
||||
return leftPtr.val === rightPtr.val && check(leftPtr.left, rightPtr.right) && check(leftPtr.right, rightPtr.left)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
@ -419,6 +419,239 @@ public:
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
// 102.二叉树的层序遍历
|
||||
class Solution {
|
||||
public List<List<Integer>> resList = new ArrayList<List<Integer>>();
|
||||
|
||||
public List<List<Integer>> levelOrder(TreeNode root) {
|
||||
//checkFun01(root,0);
|
||||
checkFun02(root);
|
||||
|
||||
return resList;
|
||||
}
|
||||
|
||||
//DFS--递归方式
|
||||
public void checkFun01(TreeNode node, Integer deep) {
|
||||
if (node == null) return;
|
||||
deep++;
|
||||
|
||||
if (resList.size() < deep) {
|
||||
//当层级增加时,list的Item也增加,利用list的索引值进行层级界定
|
||||
List<Integer> item = new ArrayList<Integer>();
|
||||
resList.add(item);
|
||||
}
|
||||
resList.get(deep - 1).add(node.val);
|
||||
|
||||
checkFun01(node.left, deep);
|
||||
checkFun01(node.right, deep);
|
||||
}
|
||||
|
||||
//BFS--迭代方式--借助队列
|
||||
public void checkFun02(TreeNode node) {
|
||||
if (node == null) return;
|
||||
Queue<TreeNode> que = new LinkedList<TreeNode>();
|
||||
que.offer(node);
|
||||
|
||||
while (!que.isEmpty()) {
|
||||
List<Integer> itemList = new ArrayList<Integer>();
|
||||
int len = que.size();
|
||||
|
||||
while (len > 0) {
|
||||
TreeNode tmpNode = que.poll();
|
||||
itemList.add(tmpNode.val);
|
||||
|
||||
if (tmpNode.left != null) que.offer(tmpNode.left);
|
||||
if (tmpNode.right != null) que.offer(tmpNode.right);
|
||||
len--;
|
||||
}
|
||||
|
||||
resList.add(itemList);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 107. 二叉树的层序遍历 II
|
||||
public class N0107 {
|
||||
|
||||
/**
|
||||
* 解法:队列,迭代。
|
||||
* 层序遍历,再翻转数组即可。
|
||||
*/
|
||||
public List<List<Integer>> solution1(TreeNode root) {
|
||||
List<List<Integer>> list = new ArrayList<>();
|
||||
Deque<TreeNode> que = new LinkedList<>();
|
||||
|
||||
if (root == null) {
|
||||
return list;
|
||||
}
|
||||
|
||||
que.offerLast(root);
|
||||
while (!que.isEmpty()) {
|
||||
List<Integer> levelList = new ArrayList<>();
|
||||
|
||||
int levelSize = que.size();
|
||||
for (int i = 0; i < levelSize; i++) {
|
||||
TreeNode peek = que.peekFirst();
|
||||
levelList.add(que.pollFirst().val);
|
||||
|
||||
if (peek.left != null) {
|
||||
que.offerLast(peek.left);
|
||||
}
|
||||
if (peek.right != null) {
|
||||
que.offerLast(peek.right);
|
||||
}
|
||||
}
|
||||
list.add(levelList);
|
||||
}
|
||||
|
||||
List<List<Integer>> result = new ArrayList<>();
|
||||
for (int i = list.size() - 1; i >= 0; i-- ) {
|
||||
result.add(list.get(i));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// 199.二叉树的右视图
|
||||
public class N0199 {
|
||||
/**
|
||||
* 解法:队列,迭代。
|
||||
* 每次返回每层的最后一个字段即可。
|
||||
*
|
||||
* 小优化:每层右孩子先入队。代码略。
|
||||
*/
|
||||
public List<Integer> rightSideView(TreeNode root) {
|
||||
List<Integer> list = new ArrayList<>();
|
||||
Deque<TreeNode> que = new LinkedList<>();
|
||||
|
||||
if (root == null) {
|
||||
return list;
|
||||
}
|
||||
|
||||
que.offerLast(root);
|
||||
while (!que.isEmpty()) {
|
||||
int levelSize = que.size();
|
||||
|
||||
for (int i = 0; i < levelSize; i++) {
|
||||
TreeNode poll = que.pollFirst();
|
||||
|
||||
if (poll.left != null) {
|
||||
que.addLast(poll.left);
|
||||
}
|
||||
if (poll.right != null) {
|
||||
que.addLast(poll.right);
|
||||
}
|
||||
|
||||
if (i == levelSize - 1) {
|
||||
list.add(poll.val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
// 637. 二叉树的层平均值
|
||||
public class N0637 {
|
||||
|
||||
/**
|
||||
* 解法:队列,迭代。
|
||||
* 每次返回每层的最后一个字段即可。
|
||||
*/
|
||||
public List<Double> averageOfLevels(TreeNode root) {
|
||||
List<Double> list = new ArrayList<>();
|
||||
Deque<TreeNode> que = new LinkedList<>();
|
||||
|
||||
if (root == null) {
|
||||
return list;
|
||||
}
|
||||
|
||||
que.offerLast(root);
|
||||
while (!que.isEmpty()) {
|
||||
TreeNode peek = que.peekFirst();
|
||||
|
||||
int levelSize = que.size();
|
||||
double levelSum = 0.0;
|
||||
for (int i = 0; i < levelSize; i++) {
|
||||
TreeNode poll = que.pollFirst();
|
||||
|
||||
levelSum += poll.val;
|
||||
|
||||
if (poll.left != null) {
|
||||
que.addLast(poll.left);
|
||||
}
|
||||
if (poll.right != null) {
|
||||
que.addLast(poll.right);
|
||||
}
|
||||
}
|
||||
list.add(levelSum / levelSize);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
// 429. N 叉树的层序遍历
|
||||
public class N0429 {
|
||||
/**
|
||||
* 解法1:队列,迭代。
|
||||
*/
|
||||
public List<List<Integer>> levelOrder(Node root) {
|
||||
List<List<Integer>> list = new ArrayList<>();
|
||||
Deque<Node> que = new LinkedList<>();
|
||||
|
||||
if (root == null) {
|
||||
return list;
|
||||
}
|
||||
|
||||
que.offerLast(root);
|
||||
while (!que.isEmpty()) {
|
||||
int levelSize = que.size();
|
||||
List<Integer> levelList = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < levelSize; i++) {
|
||||
Node poll = que.pollFirst();
|
||||
|
||||
levelList.add(poll.val);
|
||||
|
||||
List<Node> children = poll.children;
|
||||
if (children == null || children.size() == 0) {
|
||||
continue;
|
||||
}
|
||||
for (Node child : children) {
|
||||
if (child != null) {
|
||||
que.offerLast(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
list.add(levelList);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
class Node {
|
||||
public int val;
|
||||
public List<Node> children;
|
||||
|
||||
public Node() {}
|
||||
|
||||
public Node(int _val) {
|
||||
val = _val;
|
||||
}
|
||||
|
||||
public Node(int _val, List<Node> _children) {
|
||||
val = _val;
|
||||
children = _children;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Python:
|
||||
|
||||
@ -427,7 +660,6 @@ Go:
|
||||
|
||||
|
||||
|
||||
|
||||
-----------------------
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
|
@ -232,6 +232,52 @@ public:
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
/**
|
||||
* 递归法
|
||||
*/
|
||||
public int maxDepth(TreeNode root) {
|
||||
if (root == null) {
|
||||
return 0;
|
||||
}
|
||||
int leftDepth = maxDepth(root.left);
|
||||
int rightDepth = maxDepth(root.right);
|
||||
return Math.max(leftDepth, rightDepth) + 1;
|
||||
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
/**
|
||||
* 迭代法,使用层序遍历
|
||||
*/
|
||||
public int maxDepth(TreeNode root) {
|
||||
if(root == null) {
|
||||
return 0;
|
||||
}
|
||||
Deque<TreeNode> deque = new LinkedList<>();
|
||||
deque.offer(root);
|
||||
int depth = 0;
|
||||
while (!deque.isEmpty()) {
|
||||
int size = deque.size();
|
||||
depth++;
|
||||
for (int i = 0; i < size; i++) {
|
||||
TreeNode poll = deque.poll();
|
||||
if (poll.left != null) {
|
||||
deque.offer(poll.left);
|
||||
}
|
||||
if (poll.right != null) {
|
||||
deque.offer(poll.right);
|
||||
}
|
||||
}
|
||||
}
|
||||
return depth;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
@ -239,10 +285,16 @@ Python:
|
||||
Go:
|
||||
|
||||
|
||||
|
||||
JavaScript
|
||||
```javascript
|
||||
var maxDepth = function(root) {
|
||||
if (!root) return root
|
||||
return 1 + Math.max(maxDepth(root.left), maxDepth(root.right))
|
||||
};
|
||||
```
|
||||
|
||||
-----------------------
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -582,7 +582,40 @@ tree2 的前序遍历是[1 2 3], 后序遍历是[3 2 1]。
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public TreeNode buildTree(int[] inorder, int[] postorder) {
|
||||
return buildTree1(inorder, 0, inorder.length, postorder, 0, postorder.length);
|
||||
}
|
||||
public TreeNode buildTree1(int[] inorder, int inLeft, int inRight,
|
||||
int[] postorder, int postLeft, int postRight) {
|
||||
// 没有元素了
|
||||
if (inRight - inLeft < 1) {
|
||||
return null;
|
||||
}
|
||||
// 只有一个元素了
|
||||
if (inRight - inLeft == 1) {
|
||||
return new TreeNode(inorder[inLeft]);
|
||||
}
|
||||
// 后序数组postorder里最后一个即为根结点
|
||||
int rootVal = postorder[postRight - 1];
|
||||
TreeNode root = new TreeNode(rootVal);
|
||||
int rootIndex = 0;
|
||||
// 根据根结点的值找到该值在中序数组inorder里的位置
|
||||
for (int i = inLeft; i < inRight; i++) {
|
||||
if (inorder[i] == rootVal) {
|
||||
rootIndex = i;
|
||||
}
|
||||
}
|
||||
// 根据rootIndex划分左右子树
|
||||
root.left = buildTree1(inorder, inLeft, rootIndex,
|
||||
postorder, postLeft, postLeft + (rootIndex - inLeft));
|
||||
root.right = buildTree1(inorder, rootIndex + 1, inRight,
|
||||
postorder, postLeft + (rootIndex - inLeft), postRight - 1);
|
||||
return root;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
@ -590,10 +623,24 @@ Python:
|
||||
Go:
|
||||
|
||||
|
||||
|
||||
JavaScript
|
||||
```javascript
|
||||
var buildTree = function(inorder, postorder) {
|
||||
if (!postorder.length) return null
|
||||
|
||||
let root = new TreeNode(postorder[postorder.length - 1])
|
||||
|
||||
let index = inorder.findIndex(number => number === root.val)
|
||||
|
||||
root.left = buildTree(inorder.slice(0, index), postorder.slice(0, index))
|
||||
root.right = buildTree(inorder.slice(index + 1, inorder.length), postorder.slice(index, postorder.length - 1))
|
||||
|
||||
return root
|
||||
};
|
||||
```
|
||||
|
||||
-----------------------
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -209,7 +209,28 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```Java
|
||||
class Solution {
|
||||
public TreeNode sortedArrayToBST(int[] nums) {
|
||||
return sortedArrayToBST(nums, 0, nums.length);
|
||||
}
|
||||
|
||||
public TreeNode sortedArrayToBST(int[] nums, int left, int right) {
|
||||
if (left >= right) {
|
||||
return null;
|
||||
}
|
||||
if (right - left == 1) {
|
||||
return new TreeNode(nums[left]);
|
||||
}
|
||||
int mid = left + (right - left) / 2;
|
||||
TreeNode root = new TreeNode(nums[mid]);
|
||||
root.left = sortedArrayToBST(nums, left, mid);
|
||||
root.right = sortedArrayToBST(nums, mid + 1, right);
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
@ -223,4 +244,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -353,15 +353,187 @@ public:
|
||||
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
/**
|
||||
* 递归法
|
||||
*/
|
||||
public boolean isBalanced(TreeNode root) {
|
||||
return getHeight(root) != -1;
|
||||
}
|
||||
|
||||
private int getHeight(TreeNode root) {
|
||||
if (root == null) {
|
||||
return 0;
|
||||
}
|
||||
int leftHeight = getHeight(root.left);
|
||||
if (leftHeight == -1) {
|
||||
return -1;
|
||||
}
|
||||
int rightHeight = getHeight(root.right);
|
||||
if (rightHeight == -1) {
|
||||
return -1;
|
||||
}
|
||||
// 左右子树高度差大于1,return -1表示已经不是平衡树了
|
||||
if (Math.abs(leftHeight - rightHeight) > 1) {
|
||||
return -1;
|
||||
}
|
||||
return Math.max(leftHeight, rightHeight) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
class Solution {
|
||||
/**
|
||||
* 迭代法,效率较低,计算高度时会重复遍历
|
||||
* 时间复杂度:O(n^2)
|
||||
*/
|
||||
public boolean isBalanced(TreeNode root) {
|
||||
if (root == null) {
|
||||
return true;
|
||||
}
|
||||
Stack<TreeNode> stack = new Stack<>();
|
||||
TreeNode pre = null;
|
||||
while (root!= null || !stack.isEmpty()) {
|
||||
while (root != null) {
|
||||
stack.push(root);
|
||||
root = root.left;
|
||||
}
|
||||
TreeNode inNode = stack.peek();
|
||||
// 右结点为null或已经遍历过
|
||||
if (inNode.right == null || inNode.right == pre) {
|
||||
// 比较左右子树的高度差,输出
|
||||
if (Math.abs(getHeight(inNode.left) - getHeight(inNode.right)) > 1) {
|
||||
return false;
|
||||
}
|
||||
stack.pop();
|
||||
pre = inNode;
|
||||
root = null;// 当前结点下,没有要遍历的结点了
|
||||
} else {
|
||||
root = inNode.right;// 右结点还没遍历,遍历右结点
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 层序遍历,求结点的高度
|
||||
*/
|
||||
public int getHeight(TreeNode root) {
|
||||
if (root == null) {
|
||||
return 0;
|
||||
}
|
||||
Deque<TreeNode> deque = new LinkedList<>();
|
||||
deque.offer(root);
|
||||
int depth = 0;
|
||||
while (!deque.isEmpty()) {
|
||||
int size = deque.size();
|
||||
depth++;
|
||||
for (int i = 0; i < size; i++) {
|
||||
TreeNode poll = deque.poll();
|
||||
if (poll.left != null) {
|
||||
deque.offer(poll.left);
|
||||
}
|
||||
if (poll.right != null) {
|
||||
deque.offer(poll.right);
|
||||
}
|
||||
}
|
||||
}
|
||||
return depth;
|
||||
}
|
||||
}
|
||||
|
||||
class Solution {
|
||||
/**
|
||||
* 优化迭代法,针对暴力迭代法的getHeight方法做优化,利用TreeNode.val来保存当前结点的高度,这样就不会有重复遍历
|
||||
* 获取高度算法时间复杂度可以降到O(1),总的时间复杂度降为O(n)。
|
||||
* <p>
|
||||
* 时间复杂度:O(n)
|
||||
*/
|
||||
public boolean isBalanced(TreeNode root) {
|
||||
if (root == null) {
|
||||
return true;
|
||||
}
|
||||
Stack<TreeNode> stack = new Stack<>();
|
||||
TreeNode pre = null;
|
||||
while (root != null || !stack.isEmpty()) {
|
||||
while (root != null) {
|
||||
stack.push(root);
|
||||
root = root.left;
|
||||
}
|
||||
TreeNode inNode = stack.peek();
|
||||
// 右结点为null或已经遍历过
|
||||
if (inNode.right == null || inNode.right == pre) {
|
||||
// 输出
|
||||
if (Math.abs(getHeight(inNode.left) - getHeight(inNode.right)) > 1) {
|
||||
return false;
|
||||
}
|
||||
stack.pop();
|
||||
pre = inNode;
|
||||
root = null;// 当前结点下,没有要遍历的结点了
|
||||
} else {
|
||||
root = inNode.right;// 右结点还没遍历,遍历右结点
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 求结点的高度
|
||||
*/
|
||||
public int getHeight(TreeNode root) {
|
||||
if (root == null) {
|
||||
return 0;
|
||||
}
|
||||
int leftHeight = root.left != null ? root.left.val : 0;
|
||||
int rightHeight = root.right != null ? root.right.val : 0;
|
||||
int height = Math.max(leftHeight, rightHeight) + 1;
|
||||
root.val = height;// 用TreeNode.val来保存当前结点的高度
|
||||
return height;
|
||||
}
|
||||
}
|
||||
// LeetCode题解链接:https://leetcode-cn.com/problems/balanced-binary-tree/solution/110-ping-heng-er-cha-shu-di-gui-fa-bao-l-yqr3/
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
Go:
|
||||
|
||||
```Go
|
||||
func isBalanced(root *TreeNode) bool {
|
||||
if root==nil{
|
||||
return true
|
||||
}
|
||||
if !isBalanced(root.Left) || !isBalanced(root.Right){
|
||||
return false
|
||||
}
|
||||
LeftH:=maxdepth(root.Left)+1
|
||||
RightH:=maxdepth(root.Right)+1
|
||||
if abs(LeftH-RightH)>1{
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
func maxdepth(root *TreeNode)int{
|
||||
if root==nil{
|
||||
return 0
|
||||
}
|
||||
return max(maxdepth(root.Left),maxdepth(root.Right))+1
|
||||
}
|
||||
func max(a,b int)int{
|
||||
if a>b{
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
func abs(a int)int{
|
||||
if a<0{
|
||||
return -a
|
||||
}
|
||||
return a
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
@ -195,9 +195,109 @@ public:
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
/**
|
||||
* 递归法,相比求MaxDepth要复杂点
|
||||
* 因为最小深度是从根节点到最近**叶子节点**的最短路径上的节点数量
|
||||
*/
|
||||
public int minDepth(TreeNode root) {
|
||||
if (root == null) {
|
||||
return 0;
|
||||
}
|
||||
int leftDepth = minDepth(root.left);
|
||||
int rightDepth = minDepth(root.right);
|
||||
if (root.left == null) {
|
||||
return rightDepth + 1;
|
||||
}
|
||||
if (root.right == null) {
|
||||
return leftDepth + 1;
|
||||
}
|
||||
// 左右结点都不为null
|
||||
return Math.min(leftDepth, rightDepth) + 1;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
/**
|
||||
* 迭代法,层序遍历
|
||||
*/
|
||||
public int minDepth(TreeNode root) {
|
||||
if (root == null) {
|
||||
return 0;
|
||||
}
|
||||
Deque<TreeNode> deque = new LinkedList<>();
|
||||
deque.offer(root);
|
||||
int depth = 0;
|
||||
while (!deque.isEmpty()) {
|
||||
int size = deque.size();
|
||||
depth++;
|
||||
for (int i = 0; i < size; i++) {
|
||||
TreeNode poll = deque.poll();
|
||||
if (poll.left == null && poll.right == null) {
|
||||
// 是叶子结点,直接返回depth,因为从上往下遍历,所以该值就是最小值
|
||||
return depth;
|
||||
}
|
||||
if (poll.left != null) {
|
||||
deque.offer(poll.left);
|
||||
}
|
||||
if (poll.right != null) {
|
||||
deque.offer(poll.right);
|
||||
}
|
||||
}
|
||||
}
|
||||
return depth;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
递归法:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def minDepth(self, root: TreeNode) -> int:
|
||||
if not root:
|
||||
return 0
|
||||
if not root.left and not root.right:
|
||||
return 1
|
||||
|
||||
min_depth = 10**9
|
||||
if root.left:
|
||||
min_depth = min(self.minDepth(root.left), min_depth) # 获得左子树的最小高度
|
||||
if root.right:
|
||||
min_depth = min(self.minDepth(root.right), min_depth) # 获得右子树的最小高度
|
||||
return min_depth + 1
|
||||
```
|
||||
|
||||
迭代法:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def minDepth(self, root: TreeNode) -> int:
|
||||
if not root:
|
||||
return 0
|
||||
que = deque()
|
||||
que.append(root)
|
||||
res = 1
|
||||
|
||||
while que:
|
||||
for _ in range(len(que)):
|
||||
node = que.popleft()
|
||||
# 当左右孩子都为空的时候,说明是最低点的一层了,退出
|
||||
if not node.left and not node.right:
|
||||
return res
|
||||
if node.left is not None:
|
||||
que.append(node.left)
|
||||
if node.right is not None:
|
||||
que.append(node.right)
|
||||
res += 1
|
||||
return res
|
||||
```
|
||||
|
||||
|
||||
Go:
|
||||
|
||||
|
@ -305,13 +305,121 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```Java
|
||||
class Solution {
|
||||
public boolean hasPathSum(TreeNode root, int targetSum) {
|
||||
if (root == null) {
|
||||
return false;
|
||||
}
|
||||
targetSum -= root.val;
|
||||
// 叶子结点
|
||||
if (root.left == null && root.right == null) {
|
||||
return targetSum == 0;
|
||||
}
|
||||
if (root.left != null) {
|
||||
boolean left = hasPathSum(root.left, targetSum);
|
||||
if (left) {// 已经找到
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (root.right != null) {
|
||||
boolean right = hasPathSum(root.right, targetSum);
|
||||
if (right) {// 已经找到
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// LC112 简洁方法
|
||||
class Solution {
|
||||
public boolean hasPathSum(TreeNode root, int targetSum) {
|
||||
|
||||
if (root == null) return false; // 为空退出
|
||||
|
||||
// 叶子节点判断是否符合
|
||||
if (root.left == null && root.right == null) return root.val == targetSum;
|
||||
|
||||
// 求两侧分支的路径和
|
||||
return hasPathSum(root.left, targetSum - root.val) || hasPathSum(root.right, targetSum - root.val);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
Go:
|
||||
|
||||
JavaScript:
|
||||
|
||||
0112.路径总和
|
||||
|
||||
```javascript
|
||||
/**
|
||||
* @param {TreeNode} root
|
||||
* @param {number} targetSum
|
||||
* @return {boolean}
|
||||
*/
|
||||
let hasPathSum = function (root, targetSum) {
|
||||
// 递归法
|
||||
const traversal = (node, cnt) => {
|
||||
// 遇到叶子节点,并且计数为0
|
||||
if (cnt === 0 && !node.left && !node.right) return true;
|
||||
// 遇到叶子节点而没有找到合适的边(计数不为0),直接返回
|
||||
if (!node.left && !node.right) return false;
|
||||
|
||||
// 左(空节点不遍历).遇到叶子节点返回true,则直接返回true
|
||||
if (node.left && traversal(node.left, cnt - node.left.val)) return true;
|
||||
// 右(空节点不遍历)
|
||||
if (node.right && traversal(node.right, cnt - node.right.val)) return true;
|
||||
return false;
|
||||
};
|
||||
if (!root) return false;
|
||||
return traversal(root, targetSum - root.val);
|
||||
|
||||
// 精简代码:
|
||||
// if (!root) return false;
|
||||
// if (!root.left && !root.right && targetSum === root.val) return true;
|
||||
// return hasPathSum(root.left, targetSum - root.val) || hasPathSum(root.right, targetSum - root.val);
|
||||
};
|
||||
```
|
||||
|
||||
0113.路径总和-ii
|
||||
|
||||
```javascript
|
||||
let pathSum = function (root, targetSum) {
|
||||
// 递归法
|
||||
// 要遍历整个树找到所有路径,所以递归函数不需要返回值, 与112不同
|
||||
const res = [];
|
||||
const travelsal = (node, cnt, path) => {
|
||||
// 遇到了叶子节点且找到了和为sum的路径
|
||||
if (cnt === 0 && !node.left && !node.right) {
|
||||
res.push([...path]); // 不能写res.push(path), 要深拷贝
|
||||
return;
|
||||
}
|
||||
if (!node.left && !node.right) return; // 遇到叶子节点而没有找到合适的边,直接返回
|
||||
// 左 (空节点不遍历)
|
||||
if (node.left) {
|
||||
path.push(node.left.val);
|
||||
travelsal(node.left, cnt - node.left.val, path); // 递归
|
||||
path.pop(); // 回溯
|
||||
}
|
||||
// 右 (空节点不遍历)
|
||||
if (node.right) {
|
||||
path.push(node.right.val);
|
||||
travelsal(node.right, cnt - node.right.val, path); // 递归
|
||||
path.pop(); // 回溯
|
||||
}
|
||||
return;
|
||||
};
|
||||
if (!root) return res;
|
||||
travelsal(root, targetSum - root.val, [root.val]); // 把根节点放进路径
|
||||
return res;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
@ -319,4 +427,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -198,12 +198,52 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public int maxProfit(int[] prices) {
|
||||
int minprice = Integer.MAX_VALUE;
|
||||
int maxprofit = 0;
|
||||
for (int i = 0; i < prices.length; i++) {
|
||||
if (prices[i] < minprice) {
|
||||
minprice = prices[i];
|
||||
} else if (prices[i] - minprice > maxprofit) {
|
||||
maxprofit = prices[i] - minprice;
|
||||
}
|
||||
}
|
||||
return maxprofit;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
Go:
|
||||
```Go
|
||||
func maxProfit(prices []int) int {
|
||||
length:=len(prices)
|
||||
if length==0{return 0}
|
||||
dp:=make([][]int,length)
|
||||
for i:=0;i<length;i++{
|
||||
dp[i]=make([]int,2)
|
||||
}
|
||||
|
||||
dp[0][0]=-prices[0]
|
||||
dp[0][1]=0
|
||||
for i:=1;i<length;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[length-1][1]
|
||||
}
|
||||
|
||||
func max(a,b int)int {
|
||||
if a>b{
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
@ -135,10 +135,33 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public int maxProfit(int[] prices) {
|
||||
int sum = 0;
|
||||
int profit = 0;
|
||||
int buy = prices[0];
|
||||
for (int i = 1; i < prices.length; i++) {
|
||||
profit = prices[i] - buy;
|
||||
if (profit > 0) {
|
||||
sum += profit;
|
||||
}
|
||||
buy = prices[i];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def maxProfit(self, prices: List[int]) -> int:
|
||||
result = 0
|
||||
for i in range(1, len(prices)):
|
||||
result += max(prices[i] - prices[i - 1], 0)
|
||||
return result
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
@ -149,4 +172,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -133,7 +133,41 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```java
|
||||
// 动态规划
|
||||
class Solution
|
||||
// 实现1:二维数组存储
|
||||
// 可以将每天持有与否的情况分别用 dp[i][0] 和 dp[i][1] 来进行存储
|
||||
// 时间复杂度:O(n),空间复杂度O(n)
|
||||
public int maxProfit(int[] prices) {
|
||||
int n = prices.length;
|
||||
int[][] dp = new int[n][2]; // 创建二维数组存储状态
|
||||
dp[0][0] = 0; // 初始状态
|
||||
dp[0][1] = -prices[0];
|
||||
for (int i = 1; i < n; ++i) {
|
||||
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]); // 第 i 天,没有股票
|
||||
dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]); // 第 i 天,持有股票
|
||||
}
|
||||
return dp[n - 1][0]; // 卖出股票收益高于持有股票收益,因此取[0]
|
||||
}
|
||||
|
||||
// 实现2:变量存储
|
||||
// 第一种方法需要用二维数组存储,有空间开销,其实关心的仅仅是前一天的状态,不关注更多的历史信息
|
||||
// 因此,可以仅保存前一天的信息存入 dp0、dp1 这 2 个变量即可
|
||||
// 时间复杂度:O(n),空间复杂度O(1)
|
||||
public int maxProfit(int[] prices) {
|
||||
int n = prices.length;
|
||||
int dp0 = 0, dp1 = -prices[0]; // 定义变量,存储初始状态
|
||||
for (int i = 1; i < n; ++i) {
|
||||
int newDp0 = Math.max(dp0, dp1 + prices[i]); // 第 i 天,没有股票
|
||||
int newDp1 = Math.max(dp1, dp0 - prices[i]); // 第 i 天,持有股票
|
||||
dp0 = newDp0;
|
||||
dp1 = newDp1;
|
||||
}
|
||||
return dp0;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
@ -250,7 +250,46 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```Java
|
||||
class Solution {
|
||||
List<List<String>> lists = new ArrayList<>();
|
||||
Deque<String> deque = new LinkedList<>();
|
||||
|
||||
public List<List<String>> partition(String s) {
|
||||
backTracking(s, 0);
|
||||
return lists;
|
||||
}
|
||||
|
||||
private void backTracking(String s, int startIndex) {
|
||||
//如果起始位置大于s的大小,说明找到了一组分割方案
|
||||
if (startIndex >= s.length()) {
|
||||
lists.add(new ArrayList(deque));
|
||||
return;
|
||||
}
|
||||
for (int i = startIndex; i < s.length(); i++) {
|
||||
//如果是回文子串,则记录
|
||||
if (isPalindrome(s, startIndex, i)) {
|
||||
String str = s.substring(startIndex, i + 1);
|
||||
deque.addLast(str);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
//起始位置后移,保证不重复
|
||||
backTracking(s, i + 1);
|
||||
deque.removeLast();
|
||||
}
|
||||
}
|
||||
//判断是否是回文串
|
||||
private boolean isPalindrome(String s, int startIndex, int end) {
|
||||
for (int i = startIndex, j = end; i < j; i++, j--) {
|
||||
if (s.charAt(i) != s.charAt(j)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
@ -199,10 +199,45 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```java
|
||||
class Solution {
|
||||
public int canCompleteCircuit(int[] gas, int[] cost) {
|
||||
int sum = 0;
|
||||
int min = 0;
|
||||
for (int i = 0; i < gas.length; i++) {
|
||||
sum += (gas[i] - cost[i]);
|
||||
min = Math.min(sum, min);
|
||||
}
|
||||
|
||||
if (sum < 0) return -1;
|
||||
if (min >= 0) return 0;
|
||||
|
||||
for (int i = gas.length - 1; i > 0; i--) {
|
||||
min += (gas[i] - cost[i]);
|
||||
if (min >= 0) return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
|
||||
start = 0
|
||||
curSum = 0
|
||||
totalSum = 0
|
||||
for i in range(len(gas)):
|
||||
curSum += gas[i] - cost[i]
|
||||
totalSum += gas[i] - cost[i]
|
||||
if curSum < 0:
|
||||
curSum = 0
|
||||
start = i + 1
|
||||
if totalSum < 0: return -1
|
||||
return start
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
|
@ -130,10 +130,49 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```java
|
||||
class Solution {
|
||||
public int candy(int[] ratings) {
|
||||
int[] candy = new int[ratings.length];
|
||||
for (int i = 0; i < candy.length; i++) {
|
||||
candy[i] = 1;
|
||||
}
|
||||
|
||||
for (int i = 1; i < ratings.length; i++) {
|
||||
if (ratings[i] > ratings[i - 1]) {
|
||||
candy[i] = candy[i - 1] + 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = ratings.length - 2; i >= 0; i--) {
|
||||
if (ratings[i] > ratings[i + 1]) {
|
||||
candy[i] = Math.max(candy[i],candy[i + 1] + 1);
|
||||
}
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
for (int i = 0; i < candy.length; i++) {
|
||||
count += candy[i];
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def candy(self, ratings: List[int]) -> int:
|
||||
candyVec = [1] * len(ratings)
|
||||
for i in range(1, len(ratings)):
|
||||
if ratings[i] > ratings[i - 1]:
|
||||
candyVec[i] = candyVec[i - 1] + 1
|
||||
for j in range(len(ratings) - 2, -1, -1):
|
||||
if ratings[j] > ratings[j + 1]:
|
||||
candyVec[j] = max(candyVec[j], candyVec[j + 1] + 1)
|
||||
return sum(candyVec)
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
|
@ -232,7 +232,23 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```java
|
||||
class Solution {
|
||||
public boolean wordBreak(String s, List<String> wordDict) {
|
||||
boolean[] valid = new boolean[s.length() + 1];
|
||||
valid[0] = true;
|
||||
for (int i = 1; i <= s.length(); i++) {
|
||||
for (int j = 0; j < i; j++) {
|
||||
if (wordDict.contains(s.substring(j,i)) && valid[j]) {
|
||||
valid[i] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return valid[s.length()];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
@ -246,4 +262,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -186,6 +186,29 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```java
|
||||
public class Solution {
|
||||
public ListNode detectCycle(ListNode head) {
|
||||
ListNode slow = head;
|
||||
ListNode fast = head;
|
||||
while (fast != null && fast.next != null) {
|
||||
slow = slow.next;
|
||||
fast = fast.next.next;
|
||||
if (slow == fast) {// 有环
|
||||
ListNode index1 = fast;
|
||||
ListNode index2 = head;
|
||||
// 两个指针,从头结点和相遇结点,各走一步,直到相遇,相遇点即为环入口
|
||||
while (index1 != index2) {
|
||||
index1 = index1.next;
|
||||
index2 = index2.next;
|
||||
}
|
||||
return index1;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Python:
|
||||
|
@ -170,7 +170,32 @@ public class EvalRPN {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Go:
|
||||
```Go
|
||||
func evalRPN(tokens []string) int {
|
||||
stack := []int{}
|
||||
for _, token := range tokens {
|
||||
val, err := strconv.Atoi(token)
|
||||
if err == nil {
|
||||
stack = append(stack, val)
|
||||
} else {
|
||||
num1, num2 := stack[len(stack)-2], stack[(len(stack))-1]
|
||||
stack = stack[:len(stack)-2]
|
||||
switch token {
|
||||
case "+":
|
||||
stack = append(stack, num1+num2)
|
||||
case "-":
|
||||
stack = append(stack, num1-num2)
|
||||
case "*":
|
||||
stack = append(stack, num1*num2)
|
||||
case "/":
|
||||
stack = append(stack, num1/num2)
|
||||
}
|
||||
}
|
||||
}
|
||||
return stack[0]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
@ -141,7 +141,8 @@ void reverse(string& s, int start, int end) {
|
||||
|
||||
<img src='https://code-thinking.cdn.bcebos.com/pics/151_%E7%BF%BB%E8%BD%AC%E5%AD%97%E7%AC%A6%E4%B8%B2%E9%87%8C%E7%9A%84%E5%8D%95%E8%AF%8D.png' width=600> </img></div>
|
||||
|
||||
```
|
||||
```C++
|
||||
// 版本一
|
||||
class Solution {
|
||||
public:
|
||||
// 反转字符串s中左闭又闭的区间[start, end]
|
||||
@ -201,9 +202,42 @@ public:
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/* 主函数简单写法
|
||||
string reverseWords(string s) {
|
||||
removeExtraSpaces(s);
|
||||
reverse(s, 0, s.size() - 1);
|
||||
for(int i = 0; i < s.size(); i++) {
|
||||
int j = i;
|
||||
// 查找单词间的空格,翻转单词
|
||||
while(j < s.size() && s[j] != ' ') j++;
|
||||
reverse(s, i, j - 1);
|
||||
i = j;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
*/
|
||||
};
|
||||
```
|
||||
|
||||
当然这里的主函数reverseWords写的有一些冗余的,可以精简一些,精简之后的主函数为:
|
||||
|
||||
```C++
|
||||
// 注意这里仅仅是主函数,其他函数和版本一一致
|
||||
string reverseWords(string s) {
|
||||
removeExtraSpaces(s);
|
||||
reverse(s, 0, s.size() - 1);
|
||||
for(int i = 0; i < s.size(); i++) {
|
||||
int j = i;
|
||||
// 查找单词间的空格,翻转单词
|
||||
while(j < s.size() && s[j] != ' ') j++;
|
||||
reverse(s, i, j - 1);
|
||||
i = j;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
@ -213,6 +247,74 @@ public:
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
/**
|
||||
* 不使用Java内置方法实现
|
||||
* <p>
|
||||
* 1.去除首尾以及中间多余空格
|
||||
* 2.反转整个字符串
|
||||
* 3.反转各个单词
|
||||
*/
|
||||
public String reverseWords(String s) {
|
||||
// System.out.println("ReverseWords.reverseWords2() called with: s = [" + s + "]");
|
||||
// 1.去除首尾以及中间多余空格
|
||||
StringBuilder sb = removeSpace(s);
|
||||
// 2.反转整个字符串
|
||||
reverseString(sb, 0, sb.length() - 1);
|
||||
// 3.反转各个单词
|
||||
reverseEachWord(sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private StringBuilder removeSpace(String s) {
|
||||
// System.out.println("ReverseWords.removeSpace() called with: s = [" + s + "]");
|
||||
int start = 0;
|
||||
int end = s.length() - 1;
|
||||
while (s.charAt(start) == ' ') start++;
|
||||
while (s.charAt(end) == ' ') end--;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (start <= end) {
|
||||
char c = s.charAt(start);
|
||||
if (c != ' ' || sb.charAt(sb.length() - 1) != ' ') {
|
||||
sb.append(c);
|
||||
}
|
||||
start++;
|
||||
}
|
||||
// System.out.println("ReverseWords.removeSpace returned: sb = [" + sb + "]");
|
||||
return sb;
|
||||
}
|
||||
|
||||
/**
|
||||
* 反转字符串指定区间[start, end]的字符
|
||||
*/
|
||||
public void reverseString(StringBuilder sb, int start, int end) {
|
||||
// System.out.println("ReverseWords.reverseString() called with: sb = [" + sb + "], start = [" + start + "], end = [" + end + "]");
|
||||
while (start < end) {
|
||||
char temp = sb.charAt(start);
|
||||
sb.setCharAt(start, sb.charAt(end));
|
||||
sb.setCharAt(end, temp);
|
||||
start++;
|
||||
end--;
|
||||
}
|
||||
// System.out.println("ReverseWords.reverseString returned: sb = [" + sb + "]");
|
||||
}
|
||||
|
||||
private void reverseEachWord(StringBuilder sb) {
|
||||
int start = 0;
|
||||
int end = 1;
|
||||
int n = sb.length();
|
||||
while (start < n) {
|
||||
while (end < n && sb.charAt(end) != ' ') {
|
||||
end++;
|
||||
}
|
||||
reverseString(sb, start, end - 1);
|
||||
start = end + 1;
|
||||
end = start + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
@ -111,12 +111,56 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```Java
|
||||
// 动态规划
|
||||
class Solution {
|
||||
public int rob(int[] nums) {
|
||||
if (nums == null || nums.length == 0) return 0;
|
||||
if (nums.length == 1) return nums[0];
|
||||
|
||||
int[] dp = new int[nums.length + 1];
|
||||
dp[0] = nums[0];
|
||||
dp[1] = Math.max(dp[0], nums[1]);
|
||||
for (int i = 2; i < nums.length; i++) {
|
||||
dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
|
||||
}
|
||||
|
||||
return dp[nums.length - 1];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
Go:
|
||||
```Go
|
||||
func rob(nums []int) int {
|
||||
if len(nums)<1{
|
||||
return 0
|
||||
}
|
||||
if len(nums)==1{
|
||||
return nums[0]
|
||||
}
|
||||
if len(nums)==2{
|
||||
return max(nums[0],nums[1])
|
||||
}
|
||||
dp :=make([]int,len(nums))
|
||||
dp[0]=nums[0]
|
||||
dp[1]=max(nums[0],nums[1])
|
||||
for i:=2;i<len(nums);i++{
|
||||
dp[i]=max(dp[i-2]+nums[i],dp[i-1])
|
||||
}
|
||||
return dp[len(dp)-1]
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a>b{
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
@ -84,7 +84,28 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```java
|
||||
class Solution {
|
||||
public boolean isHappy(int n) {
|
||||
Set<Integer> record = new HashSet<>();
|
||||
while (n != 1 && !record.contains(n)) {
|
||||
record.add(n);
|
||||
n = getNextNumber(n);
|
||||
}
|
||||
return n == 1;
|
||||
}
|
||||
|
||||
private int getNextNumber(int n) {
|
||||
int res = 0;
|
||||
while (n > 0) {
|
||||
int temp = n % 10;
|
||||
res += temp * temp;
|
||||
n = n / 10;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
@ -138,7 +138,63 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```java
|
||||
/**
|
||||
* 添加虚节点方式
|
||||
* 时间复杂度 O(n)
|
||||
* 空间复杂度 O(1)
|
||||
* @param head
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public ListNode removeElements(ListNode head, int val) {
|
||||
if (head == null) {
|
||||
return head;
|
||||
}
|
||||
// 因为删除可能涉及到头节点,所以设置dummy节点,统一操作
|
||||
ListNode dummy = new ListNode(-1, head);
|
||||
ListNode pre = dummy;
|
||||
ListNode cur = head;
|
||||
while (cur != null) {
|
||||
if (cur.val == val) {
|
||||
pre.next = cur.next;
|
||||
} else {
|
||||
pre = cur;
|
||||
}
|
||||
cur = cur.next;
|
||||
}
|
||||
return dummy.next;
|
||||
}
|
||||
/**
|
||||
* 不添加虚拟节点方式
|
||||
* 时间复杂度 O(n)
|
||||
* 空间复杂度 O(1)
|
||||
* @param head
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public ListNode removeElements(ListNode head, int val) {
|
||||
while (head != null && head.val == val) {
|
||||
head = head.next;
|
||||
}
|
||||
// 已经为null,提前退出
|
||||
if (head == null) {
|
||||
return head;
|
||||
}
|
||||
// 已确定当前head.val != val
|
||||
ListNode pre = head;
|
||||
ListNode cur = head.next;
|
||||
while (cur != null) {
|
||||
if (cur.val == val) {
|
||||
pre.next = cur.next;
|
||||
} else {
|
||||
pre = cur;
|
||||
}
|
||||
cur = cur.next;
|
||||
}
|
||||
return head;
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
@ -102,7 +102,45 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```java
|
||||
// 双指针
|
||||
class Solution {
|
||||
public ListNode reverseList(ListNode head) {
|
||||
ListNode prev = null;
|
||||
ListNode cur = head;
|
||||
ListNode temp = null;
|
||||
while (cur != null) {
|
||||
temp = cur.next;// 保存下一个节点
|
||||
cur.next = prev;
|
||||
prev = cur;
|
||||
cur = temp;
|
||||
}
|
||||
return prev;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
// 递归
|
||||
class Solution {
|
||||
public ListNode reverseList(ListNode head) {
|
||||
return reverse(null, head);
|
||||
}
|
||||
|
||||
private ListNode reverse(ListNode prev, ListNode cur) {
|
||||
if (cur == null) {
|
||||
return prev;
|
||||
}
|
||||
ListNode temp = null;
|
||||
temp = cur.next;// 先保存下一个节点
|
||||
cur.next = prev;// 反转
|
||||
// 更新prev、cur位置
|
||||
prev = cur;
|
||||
cur = temp;
|
||||
return reverse(prev, cur);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
@ -116,4 +154,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -148,7 +148,25 @@ class Solution:
|
||||
|
||||
|
||||
Java:
|
||||
```java
|
||||
class Solution {
|
||||
|
||||
// 滑动窗口
|
||||
public int minSubArrayLen(int s, int[] nums) {
|
||||
int left = 0;
|
||||
int sum = 0;
|
||||
int result = Integer.MAX_VALUE;
|
||||
for (int right = 0; right < nums.length; right++) {
|
||||
sum += nums[right];
|
||||
while (sum >= s) {
|
||||
result = Math.min(result, right - left + 1);
|
||||
sum -= nums[left++];
|
||||
}
|
||||
}
|
||||
return result == Integer.MAX_VALUE ? 0 : result;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
@ -156,10 +174,25 @@ Python:
|
||||
Go:
|
||||
|
||||
|
||||
|
||||
JavaScript:
|
||||
```
|
||||
var minSubArrayLen = (target, nums) => {
|
||||
let left = 0, right = 0,win = Infinity,sum = 0;
|
||||
while(right < nums.length){
|
||||
sum += nums[right];
|
||||
while(sum >= target){
|
||||
win = right - left + 1 < win? right - left + 1 : win;
|
||||
sum -= nums[left];
|
||||
left++;
|
||||
}
|
||||
right++;
|
||||
}
|
||||
return win === Infinity? 0:win;
|
||||
};
|
||||
```
|
||||
|
||||
-----------------------
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -98,7 +98,28 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```Java
|
||||
class Solution {
|
||||
public int rob(int[] nums) {
|
||||
if (nums == null || nums.length == 0)
|
||||
return 0;
|
||||
int len = nums.length;
|
||||
if (len == 1)
|
||||
return nums[0];
|
||||
return Math.max(robAction(nums, 0, len - 1), robAction(nums, 1, len));
|
||||
}
|
||||
|
||||
int robAction(int[] nums, int start, int end) {
|
||||
int x = 0, y = 0, z = 0;
|
||||
for (int i = start; i < end; i++) {
|
||||
y = z;
|
||||
z = Math.max(y, x + nums[i]);
|
||||
x = y;
|
||||
}
|
||||
return z;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
@ -227,7 +227,39 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```java
|
||||
class Solution {
|
||||
List<List<Integer>> res = new ArrayList<>();
|
||||
List<Integer> list = new ArrayList<>();
|
||||
|
||||
public List<List<Integer>> combinationSum3(int k, int n) {
|
||||
res.clear();
|
||||
list.clear();
|
||||
backtracking(k, n, 9);
|
||||
return res;
|
||||
}
|
||||
|
||||
private void backtracking(int k, int n, int maxNum) {
|
||||
if (k == 0 && n == 0) {
|
||||
res.add(new ArrayList<>(list));
|
||||
return;
|
||||
}
|
||||
|
||||
// 因为不能重复,并且单个数字最大值是maxNum,所以sum最大值为
|
||||
// (maxNum + (maxNum - 1) + ... + (maxNum - k + 1)) == k * maxNum - k*(k - 1) / 2
|
||||
if (maxNum == 0
|
||||
|| n > k * maxNum - k * (k - 1) / 2
|
||||
|| n < (1 + k) * k / 2) {
|
||||
return;
|
||||
}
|
||||
list.add(maxNum);
|
||||
backtracking(k - 1, n - maxNum, maxNum - 1);
|
||||
list.remove(list.size() - 1);
|
||||
backtracking(k, n, maxNum - 1);
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
@ -241,4 +273,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -194,7 +194,49 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```java
|
||||
class Solution {
|
||||
// 通用递归解法
|
||||
public int countNodes(TreeNode root) {
|
||||
if(root == null) {
|
||||
return 0;
|
||||
}
|
||||
return countNodes(root.left) + countNodes(root.right) + 1;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
/**
|
||||
* 针对完全二叉树的解法
|
||||
*
|
||||
* 满二叉树的结点数为:2^depth - 1
|
||||
*/
|
||||
public int countNodes(TreeNode root) {
|
||||
if(root == null) {
|
||||
return 0;
|
||||
}
|
||||
int leftDepth = getDepth(root.left);
|
||||
int rightDepth = getDepth(root.right);
|
||||
if (leftDepth == rightDepth) {// 左子树是满二叉树
|
||||
// 2^leftDepth其实是 (2^leftDepth - 1) + 1 ,左子树 + 根结点
|
||||
return (1 << leftDepth) + countNodes(root.right);
|
||||
} else {// 右子树是满二叉树
|
||||
return (1 << rightDepth) + countNodes(root.left);
|
||||
}
|
||||
}
|
||||
|
||||
private int getDepth(TreeNode root) {
|
||||
int depth = 0;
|
||||
while (root != null) {
|
||||
root = root.left;
|
||||
depth++;
|
||||
}
|
||||
return depth;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
@ -208,4 +250,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -154,9 +154,58 @@ public:
|
||||
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```java
|
||||
class MyStack {
|
||||
|
||||
Queue<Integer> queue1; // 和栈中保持一样元素的队列
|
||||
Queue<Integer> queue2; // 辅助队列
|
||||
|
||||
/** Initialize your data structure here. */
|
||||
public MyStack() {
|
||||
queue1 = new LinkedList<>();
|
||||
queue2 = new LinkedList<>();
|
||||
}
|
||||
|
||||
/** Push element x onto stack. */
|
||||
public void push(int x) {
|
||||
queue2.offer(x); // 先放在辅助队列中
|
||||
while (!queue1.isEmpty()){
|
||||
queue2.offer(queue1.poll());
|
||||
}
|
||||
Queue<Integer> queueTemp;
|
||||
queueTemp = queue1;
|
||||
queue1 = queue2;
|
||||
queue2 = queueTemp; // 最后交换queue1和queue2,将元素都放到queue1中
|
||||
}
|
||||
|
||||
/** Removes the element on top of the stack and returns that element. */
|
||||
public int pop() {
|
||||
return queue1.poll(); // 因为queue1中的元素和栈中的保持一致,所以这个和下面两个的操作只看queue1即可
|
||||
}
|
||||
|
||||
/** Get the top element. */
|
||||
public int top() {
|
||||
return queue1.peek();
|
||||
}
|
||||
|
||||
/** Returns whether the stack is empty. */
|
||||
public boolean empty() {
|
||||
return queue1.isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Your MyQueue object will be instantiated and called as such:
|
||||
* MyQueue obj = new MyQueue();
|
||||
* obj.push(x);
|
||||
* int param_2 = obj.pop();
|
||||
* int param_3 = obj.peek();
|
||||
* boolean param_4 = obj.empty();
|
||||
*/
|
||||
```
|
||||
|
||||
|
||||
Python:
|
||||
|
||||
@ -227,4 +276,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -204,12 +204,48 @@ public:
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
/**
|
||||
* 前后序遍历都可以
|
||||
* 中序不行,因为先左孩子交换孩子,再根交换孩子(做完后,右孩子已经变成了原来的左孩子),再右孩子交换孩子(此时其实是对原来的左孩子做交换)
|
||||
*/
|
||||
public TreeNode invertTree(TreeNode root) {
|
||||
if (root == null) {
|
||||
return null;
|
||||
}
|
||||
invertTree(root.left);
|
||||
invertTree(root.right);
|
||||
swapChildren(root);
|
||||
return root;
|
||||
}
|
||||
|
||||
private void swapChildren(TreeNode root) {
|
||||
TreeNode tmp = root.left;
|
||||
root.left = root.right;
|
||||
root.right = tmp;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
Go:
|
||||
```Go
|
||||
func invertTree(root *TreeNode) *TreeNode {
|
||||
if root ==nil{
|
||||
return nil
|
||||
}
|
||||
temp:=root.Left
|
||||
root.Left=root.Right
|
||||
root.Right=temp
|
||||
|
||||
invertTree(root.Left)
|
||||
invertTree(root.Right)
|
||||
|
||||
return root
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
@ -217,4 +253,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -19,7 +19,7 @@ push(x) -- 将一个元素放入队列的尾部。
|
||||
pop() -- 从队列首部移除元素。
|
||||
peek() -- 返回队列首部的元素。
|
||||
empty() -- 返回队列是否为空。
|
||||
|
||||
|
||||
|
||||
示例:
|
||||
|
||||
@ -129,9 +129,62 @@ public:
|
||||
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```java
|
||||
class MyQueue {
|
||||
|
||||
Stack<Integer> stack1;
|
||||
Stack<Integer> stack2;
|
||||
|
||||
/** Initialize your data structure here. */
|
||||
public MyQueue() {
|
||||
stack1 = new Stack<>(); // 负责进栈
|
||||
stack2 = new Stack<>(); // 负责出栈
|
||||
}
|
||||
|
||||
/** Push element x to the back of queue. */
|
||||
public void push(int x) {
|
||||
stack1.push(x);
|
||||
}
|
||||
|
||||
/** Removes the element from in front of queue and returns that element. */
|
||||
public int pop() {
|
||||
dumpStack1();
|
||||
return stack2.pop();
|
||||
}
|
||||
|
||||
/** Get the front element. */
|
||||
public int peek() {
|
||||
dumpStack1();
|
||||
return stack2.peek();
|
||||
}
|
||||
|
||||
/** Returns whether the queue is empty. */
|
||||
public boolean empty() {
|
||||
return stack1.isEmpty() && stack2.isEmpty();
|
||||
}
|
||||
|
||||
// 如果stack2为空,那么将stack1中的元素全部放到stack2中
|
||||
private void dumpStack1(){
|
||||
if (stack2.isEmpty()){
|
||||
while (!stack1.isEmpty()){
|
||||
stack2.push(stack1.pop());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Your MyQueue object will be instantiated and called as such:
|
||||
* MyQueue obj = new MyQueue();
|
||||
* obj.push(x);
|
||||
* int param_2 = obj.pop();
|
||||
* int param_3 = obj.peek();
|
||||
* boolean param_4 = obj.empty();
|
||||
*/
|
||||
```
|
||||
|
||||
|
||||
Python:
|
||||
|
||||
@ -145,4 +198,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -29,7 +29,7 @@
|
||||
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
|
||||
输出: 2
|
||||
解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。
|
||||
|
||||
|
||||
|
||||
说明:
|
||||
|
||||
@ -229,7 +229,22 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
|
||||
while (true) {
|
||||
if (root.val > p.val && root.val > q.val) {
|
||||
root = root.left;
|
||||
} else if (root.val < p.val && root.val < q.val) {
|
||||
root = root.right;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return root;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
@ -243,4 +258,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -223,8 +223,45 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```Java
|
||||
class Solution {
|
||||
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
|
||||
return lowestCommonAncestor1(root, p, q);
|
||||
}
|
||||
public TreeNode lowestCommonAncestor1(TreeNode root, TreeNode p, TreeNode q) {
|
||||
if (root == null || root == p || root == q) {
|
||||
return root;
|
||||
}
|
||||
TreeNode left = lowestCommonAncestor1(root.left, p, q);
|
||||
TreeNode right = lowestCommonAncestor1(root.right, p, q);
|
||||
if (left != null && right != null) {// 左右子树分别找到了,说明此时的root就是要求的结果
|
||||
return root;
|
||||
}
|
||||
if (left == null) {
|
||||
return right;
|
||||
}
|
||||
return left;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
```java
|
||||
// 代码精简版
|
||||
class Solution {
|
||||
TreeNode pre;
|
||||
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
|
||||
if (root == null || root.val == p.val ||root.val == q.val) return root;
|
||||
TreeNode left = lowestCommonAncestor(root.left,p,q);
|
||||
TreeNode right = lowestCommonAncestor(root.right,p,q);
|
||||
if (left != null && right != null) return root;
|
||||
else if (left == null && right != null) return right;
|
||||
else if (left != null && right == null) return left;
|
||||
else return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
@ -237,4 +274,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -207,7 +207,60 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```Java
|
||||
//自定义数组
|
||||
class MyQueue {
|
||||
Deque<Integer> deque = new LinkedList<>();
|
||||
//弹出元素时,比较当前要弹出的数值是否等于队列出口的数值,如果相等则弹出
|
||||
//同时判断队列当前是否为空
|
||||
void poll(int val) {
|
||||
if (!deque.isEmpty() && val == deque.peek()) {
|
||||
deque.poll();
|
||||
}
|
||||
}
|
||||
//添加元素时,如果要添加的元素大于入口处的元素,就将入口元素弹出
|
||||
//保证队列元素单调递减
|
||||
//比如此时队列元素3,1,2将要入队,比1大,所以1弹出,此时队列:3,2
|
||||
void add(int val) {
|
||||
while (!deque.isEmpty() && val > deque.getLast()) {
|
||||
deque.removeLast();
|
||||
}
|
||||
deque.add(val);
|
||||
}
|
||||
//队列队顶元素始终为最大值
|
||||
int peek() {
|
||||
return deque.peek();
|
||||
}
|
||||
}
|
||||
|
||||
class Solution {
|
||||
public int[] maxSlidingWindow(int[] nums, int k) {
|
||||
if (nums.length == 1) {
|
||||
return nums;
|
||||
}
|
||||
int len = nums.length - k + 1;
|
||||
//存放结果元素的数组
|
||||
int[] res = new int[len];
|
||||
int num = 0;
|
||||
//自定义队列
|
||||
MyQueue myQueue = new MyQueue();
|
||||
//先将前k的元素放入队列
|
||||
for (int i = 0; i < k; i++) {
|
||||
myQueue.add(nums[i]);
|
||||
}
|
||||
res[num++] = myQueue.peek();
|
||||
for (int i = k; i < nums.length; i++) {
|
||||
//滑动窗口移除最前面的元素,移除是判断该元素是否放入队列
|
||||
myQueue.poll(nums[i - k]);
|
||||
//滑动窗口加入最后面的元素
|
||||
myQueue.add(nums[i]);
|
||||
//记录对应的最大值
|
||||
res[num++] = myQueue.peek();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
@ -85,18 +85,58 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```java
|
||||
class Solution {
|
||||
public boolean isAnagram(String s, String t) {
|
||||
|
||||
int[] record = new int[26];
|
||||
for (char c : s.toCharArray()) {
|
||||
record[c - 'a'] += 1;
|
||||
}
|
||||
for (char c : t.toCharArray()) {
|
||||
record[c - 'a'] -= 1;
|
||||
}
|
||||
for (int i : record) {
|
||||
if (i != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
Go:
|
||||
|
||||
|
||||
```go
|
||||
func isAnagram(s string, t string) bool {
|
||||
if len(s)!=len(t){
|
||||
return false
|
||||
}
|
||||
exists := make(map[byte]int)
|
||||
for i:=0;i<len(s);i++{
|
||||
if v,ok:=exists[s[i]];v>=0&&ok{
|
||||
exists[s[i]]=v+1
|
||||
}else{
|
||||
exists[s[i]]=1
|
||||
}
|
||||
}
|
||||
for i:=0;i<len(t);i++{
|
||||
if v,ok:=exists[t[i]];v>=1&&ok{
|
||||
exists[t[i]]=v-1
|
||||
}else{
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -280,9 +280,48 @@ public:
|
||||
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
/**
|
||||
* 递归法
|
||||
*/
|
||||
public List<String> binaryTreePaths(TreeNode root) {
|
||||
List<String> res = new ArrayList<>();
|
||||
if (root == null) {
|
||||
return res;
|
||||
}
|
||||
List<Integer> paths = new ArrayList<>();
|
||||
traversal(root, paths, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
private void traversal(TreeNode root, List<Integer> paths, List<String> res) {
|
||||
paths.add(root.val);
|
||||
// 叶子结点
|
||||
if (root.left == null && root.right == null) {
|
||||
// 输出
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < paths.size() - 1; i++) {
|
||||
sb.append(paths.get(i)).append("->");
|
||||
}
|
||||
sb.append(paths.get(paths.size() - 1));
|
||||
res.add(sb.toString());
|
||||
return;
|
||||
}
|
||||
if (root.left != null) {
|
||||
traversal(root.left, paths, res);
|
||||
paths.remove(paths.size() - 1);// 回溯
|
||||
}
|
||||
if (root.right != null) {
|
||||
traversal(root.right, paths, res);
|
||||
paths.remove(paths.size() - 1);// 回溯
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
@ -296,4 +335,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -159,7 +159,28 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
public int numSquares(int n) {
|
||||
int max = Integer.MAX_VALUE;
|
||||
int[] dp = new int[n + 1];
|
||||
//初始化
|
||||
for (int j = 0; j <= n; j++) {
|
||||
dp[j] = max;
|
||||
}
|
||||
//当和为0时,组合的个数为0
|
||||
dp[0] = 0;
|
||||
for (int i = 1; i * i <= n; i++) {
|
||||
for (int j = i * i; j <= n; j++) {
|
||||
if (dp[j - i * i] != max) {
|
||||
dp[j] = Math.min(dp[j], dp[j - i * i] + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[n];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
@ -110,7 +110,26 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
public int lengthOfLIS(int[] nums) {
|
||||
int[] dp = new int[nums.length];
|
||||
Arrays.fill(dp, 1);
|
||||
for (int i = 0; i < dp.length; i++) {
|
||||
for (int j = 0; j < i; j++) {
|
||||
if (nums[i] > nums[j]) {
|
||||
dp[i] = Math.max(dp[i], dp[j] + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
int res = 0;
|
||||
for (int i = 0; i < dp.length; i++) {
|
||||
res = Math.max(res, dp[i]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
@ -181,7 +181,31 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
public int coinChange(int[] coins, int amount) {
|
||||
int max = Integer.MAX_VALUE;
|
||||
int[] dp = new int[amount + 1];
|
||||
//初始化dp数组为最大值
|
||||
for (int j = 0; j < dp.length; j++) {
|
||||
dp[j] = max;
|
||||
}
|
||||
//当金额为0时需要的硬币数目为0
|
||||
dp[0] = 0;
|
||||
for (int i = 0; i < coins.length; i++) {
|
||||
//正序遍历:完全背包每个硬币可以选择多次
|
||||
for (int j = coins[i]; j <= amount; j++) {
|
||||
//只有dp[j-coins[i]]不是初始最大值时,该位才有选择的必要
|
||||
if (dp[j - coins[i]] != max) {
|
||||
//选择硬币数目最小的情况
|
||||
dp[j] = Math.min(dp[j], dp[j - coins[i]] + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[amount] == max ? -1 : dp[amount];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
@ -218,7 +218,72 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```Java
|
||||
class Solution {
|
||||
// 1.递归去偷,超时
|
||||
public int rob(TreeNode root) {
|
||||
if (root == null)
|
||||
return 0;
|
||||
int money = root.val;
|
||||
if (root.left != null) {
|
||||
money += rob(root.left.left) + rob(root.left.right);
|
||||
}
|
||||
if (root.right != null) {
|
||||
money += rob(root.right.left) + rob(root.right.right);
|
||||
}
|
||||
return Math.max(money, rob(root.left) + rob(root.right));
|
||||
}
|
||||
|
||||
// 2.递归去偷,记录状态
|
||||
// 执行用时:3 ms , 在所有 Java 提交中击败了 56.24% 的用户
|
||||
public int rob1(TreeNode root) {
|
||||
Map<TreeNode, Integer> memo = new HashMap<>();
|
||||
return robAction(root, memo);
|
||||
}
|
||||
|
||||
int robAction(TreeNode root, Map<TreeNode, Integer> memo) {
|
||||
if (root == null)
|
||||
return 0;
|
||||
if (memo.containsKey(root))
|
||||
return memo.get(root);
|
||||
int money = root.val;
|
||||
if (root.left != null) {
|
||||
money += robAction(root.left.left, memo) + robAction(root.left.right, memo);
|
||||
}
|
||||
if (root.right != null) {
|
||||
money += robAction(root.right.left, memo) + robAction(root.right.right, memo);
|
||||
}
|
||||
int res = Math.max(money, robAction(root.left, memo) + robAction(root.right, memo));
|
||||
memo.put(root, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
// 3.状态标记递归
|
||||
// 执行用时:0 ms , 在所有 Java 提交中击败了 100% 的用户
|
||||
// 不偷:Max(左孩子不偷,左孩子偷) + Max(又孩子不偷,右孩子偷)
|
||||
// root[0] = Math.max(rob(root.left)[0], rob(root.left)[1]) +
|
||||
// Math.max(rob(root.right)[0], rob(root.right)[1])
|
||||
// 偷:左孩子不偷+ 右孩子不偷 + 当前节点偷
|
||||
// root[1] = rob(root.left)[0] + rob(root.right)[0] + root.val;
|
||||
public int rob3(TreeNode root) {
|
||||
int[] res = robAction1(root);
|
||||
return Math.max(res[0], res[1]);
|
||||
}
|
||||
|
||||
int[] robAction1(TreeNode root) {
|
||||
int res[] = new int[2];
|
||||
if (root == null)
|
||||
return res;
|
||||
|
||||
int[] left = robAction1(root.left);
|
||||
int[] right = robAction1(root.right);
|
||||
|
||||
res[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
|
||||
res[1] = root.val + left[0] + right[0];
|
||||
return res;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
@ -140,12 +140,37 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
public void reverseString(char[] s) {
|
||||
int l = 0;
|
||||
int r = s.length - 1;
|
||||
while (l < r) {
|
||||
s[l] ^= s[r]; //构造 a ^ b 的结果,并放在 a 中
|
||||
s[r] ^= s[l]; //将 a ^ b 这一结果再 ^ b ,存入b中,此时 b = a, a = a ^ b
|
||||
s[l] ^= s[r]; //a ^ b 的结果再 ^ a ,存入 a 中,此时 b = a, a = b 完成交换
|
||||
l++;
|
||||
r--;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
Go:
|
||||
```Go
|
||||
func reverseString(s []byte) {
|
||||
left:=0
|
||||
right:=len(s)-1
|
||||
for left<right{
|
||||
s[left],s[right]=s[right],s[left]
|
||||
left++
|
||||
right--
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
@ -133,6 +133,32 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```java
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
Set<Map.Entry<Integer, Integer>> entries = map.entrySet();
|
||||
// 根据map的value值正序排,相当于一个小顶堆
|
||||
PriorityQueue<Map.Entry<Integer, Integer>> queue = new PriorityQueue<>((o1, o2) -> o1.getValue() - o2.getValue());
|
||||
for (Map.Entry<Integer, Integer> entry : entries) {
|
||||
queue.offer(entry);
|
||||
if (queue.size() > k) {
|
||||
queue.poll();
|
||||
}
|
||||
}
|
||||
for (int i = k - 1; i >= 0; i--) {
|
||||
result[i] = queue.poll().getKey();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Python:
|
||||
|
@ -76,6 +76,37 @@ public:
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
class Solution {
|
||||
public int[] intersection(int[] nums1, int[] nums2) {
|
||||
if (nums1 == null || nums1.length == 0 || nums2 == null || nums2.length == 0) {
|
||||
return new int[0];
|
||||
}
|
||||
Set<Integer> set1 = new HashSet<>();
|
||||
Set<Integer> resSet = new HashSet<>();
|
||||
//遍历数组1
|
||||
for (int i : nums1) {
|
||||
set1.add(i);
|
||||
}
|
||||
//遍历数组2的过程中判断哈希表中是否存在该元素
|
||||
for (int i : nums2) {
|
||||
if (set1.contains(i)) {
|
||||
resSet.add(i);
|
||||
}
|
||||
}
|
||||
int[] resArr = new int[resSet.size()];
|
||||
int index = 0;
|
||||
//将结果几何转为数组
|
||||
for (int i : resSet) {
|
||||
resArr[index++] = i;
|
||||
}
|
||||
return resArr;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
@ -111,7 +111,31 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
public int wiggleMaxLength(int[] nums) {
|
||||
if (nums == null || nums.length <= 1) {
|
||||
return nums.length;
|
||||
}
|
||||
//当前差值
|
||||
int curDiff = 0;
|
||||
//上一个差值
|
||||
int preDiff = 0;
|
||||
int count = 1;
|
||||
for (int i = 1; i < nums.length; i++) {
|
||||
//得到当前差值
|
||||
curDiff = nums[i] - nums[i - 1];
|
||||
//如果当前差值和上一个差值为一正一负
|
||||
//等于0的情况表示初始时的preDiff
|
||||
if ((curDiff > 0 && preDiff <= 0) || (curDiff < 0 && preDiff >= 0)) {
|
||||
count++;
|
||||
preDiff = curDiff;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
@ -148,9 +148,39 @@ C++测试用例有超过两个树相加超过int的数据,所以需要在if里
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
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] += dp[i - nums[j]];
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[target];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def combinationSum4(self, nums, target):
|
||||
dp = [0] * (target + 1)
|
||||
dp[0] = 1
|
||||
|
||||
for i in range(1, target+1):
|
||||
for j in nums:
|
||||
if i >= j:
|
||||
dp[i] += dp[i - j]
|
||||
|
||||
return dp[-1]
|
||||
```
|
||||
|
||||
|
||||
Go:
|
||||
|
||||
@ -161,4 +191,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -111,7 +111,31 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```Java
|
||||
class Solution {
|
||||
public boolean canConstruct(String ransomNote, String magazine) {
|
||||
//记录杂志字符串出现的次数
|
||||
int[] arr = new int[26];
|
||||
int temp;
|
||||
for (int i = 0; i < magazine.length(); i++) {
|
||||
temp = magazine.charAt(i) - 'a';
|
||||
arr[temp]++;
|
||||
}
|
||||
for (int i = 0; i < ransomNote.length(); i++) {
|
||||
temp = ransomNote.charAt(i) - 'a';
|
||||
//对于金信中的每一个字符都在数组中查找
|
||||
//找到相应位减一,否则找不到返回false
|
||||
if (arr[temp] > 0) {
|
||||
arr[temp]--;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
@ -159,9 +159,50 @@ public:
|
||||
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
**递归**
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public int sumOfLeftLeaves(TreeNode root) {
|
||||
if (root == null) return 0;
|
||||
int leftValue = sumOfLeftLeaves(root.left); // 左
|
||||
int rightValue = sumOfLeftLeaves(root.right); // 右
|
||||
|
||||
int midValue = 0;
|
||||
if (root.left != null && root.left.left == null && root.left.right == null) { // 中
|
||||
midValue = root.left.val;
|
||||
}
|
||||
int sum = midValue + leftValue + rightValue;
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**迭代**
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public int sumOfLeftLeaves(TreeNode root) {
|
||||
if (root == null) return 0;
|
||||
Stack<TreeNode> stack = new Stack<> ();
|
||||
stack.add(root);
|
||||
int result = 0;
|
||||
while (!stack.isEmpty()) {
|
||||
TreeNode node = stack.pop();
|
||||
if (node.left != null && node.left.left == null && node.left.right == null) {
|
||||
result += node.left.val;
|
||||
}
|
||||
if (node.right != null) stack.add(node.right);
|
||||
if (node.left != null) stack.add(node.left);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
Python:
|
||||
|
||||
@ -175,4 +216,6 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
|
||||
|
@ -185,7 +185,30 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```java
|
||||
class Solution {
|
||||
public int[][] reconstructQueue(int[][] people) {
|
||||
Arrays.sort(people, new Comparator<int[]>() {
|
||||
@Override
|
||||
public int compare(int[] o1, int[] o2) {
|
||||
if (o1[0] != o2[0]) {
|
||||
return Integer.compare(o2[0],o1[0]);
|
||||
} else {
|
||||
return Integer.compare(o1[1],o2[1]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
LinkedList<int[]> que = new LinkedList<>();
|
||||
|
||||
for (int[] p : people) {
|
||||
que.add(p[1],p);
|
||||
}
|
||||
|
||||
return que.toArray(new int[people.length][]);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
@ -199,4 +222,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -185,7 +185,41 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```Java
|
||||
class Solution {
|
||||
public boolean canPartition(int[] nums) {
|
||||
int sum = 0;
|
||||
for (int i : nums) {
|
||||
sum += i;
|
||||
}
|
||||
if ((sum & 1) == 1) {
|
||||
return false;
|
||||
}
|
||||
int length = nums.length;
|
||||
int target = sum >> 1;
|
||||
//dp[j]表示前i个元素可以找到相加等于j情况
|
||||
boolean[] dp = new boolean[target + 1];
|
||||
//对于第一个元素,只有当j=nums[0]时,才恰好填充满
|
||||
if (nums[0] <= target) {
|
||||
dp[nums[0]] = true;
|
||||
}
|
||||
|
||||
for (int i = 1; i < length; i++) {
|
||||
//j由右往左直到nums[i]
|
||||
for (int j = target; j >= nums[i]; j--) {
|
||||
//只有两种情况,要么放,要么不放
|
||||
//取其中的TRUE值
|
||||
dp[j] = dp[j] || dp[j - nums[i]];
|
||||
}
|
||||
//一旦满足,结束,因为只需要找到一组值即可
|
||||
if (dp[target]) {
|
||||
return dp[target];
|
||||
}
|
||||
}
|
||||
return dp[target];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
@ -182,7 +182,34 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```java
|
||||
class Solution {
|
||||
public int eraseOverlapIntervals(int[][] intervals) {
|
||||
if (intervals.length < 2) return 0;
|
||||
Arrays.sort(intervals, new Comparator<int[]>() {
|
||||
@Override
|
||||
public int compare(int[] o1, int[] o2) {
|
||||
if (o1[0] != o2[0]) {
|
||||
return Integer.compare(o1[1],o2[1]);
|
||||
} else {
|
||||
return Integer.compare(o2[0],o1[0]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
int count = 0;
|
||||
int edge = intervals[0][1];
|
||||
for (int i = 1; i < intervals.length; i++) {
|
||||
if (intervals[i][0] < edge) {
|
||||
count++;
|
||||
} else {
|
||||
edge = intervals[i][1];
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
@ -196,4 +223,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -251,12 +251,77 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```java
|
||||
class Solution {
|
||||
public TreeNode deleteNode(TreeNode root, int key) {
|
||||
root = delete(root,key);
|
||||
return root;
|
||||
}
|
||||
|
||||
private TreeNode delete(TreeNode root, int key) {
|
||||
if (root == null) return null;
|
||||
|
||||
if (root.val > key) {
|
||||
root.left = delete(root.left,key);
|
||||
} else if (root.val < key) {
|
||||
root.right = delete(root.right,key);
|
||||
} else {
|
||||
if (root.left == null) return root.right;
|
||||
if (root.right == null) return root.left;
|
||||
TreeNode tmp = root.right;
|
||||
while (tmp.left != null) {
|
||||
tmp = tmp.left;
|
||||
}
|
||||
root.val = tmp.val;
|
||||
root.right = delete(root.right,tmp.val);
|
||||
}
|
||||
return root;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
Go:
|
||||
```Go
|
||||
func deleteNode(root *TreeNode, key int) *TreeNode {
|
||||
if root==nil{
|
||||
return nil
|
||||
}
|
||||
if key<root.Val{
|
||||
root.Left=deleteNode(root.Left,key)
|
||||
return root
|
||||
}
|
||||
if key>root.Val{
|
||||
root.Right=deleteNode(root.Right,key)
|
||||
return root
|
||||
}
|
||||
if root.Right==nil{
|
||||
return root.Left
|
||||
}
|
||||
if root.Left==nil{
|
||||
return root.Right
|
||||
}
|
||||
minnode:=root.Right
|
||||
for minnode.Left!=nil{
|
||||
minnode=minnode.Left
|
||||
}
|
||||
root.Val=minnode.Val
|
||||
root.Right=deleteNode1(root.Right)
|
||||
return root
|
||||
}
|
||||
|
||||
func deleteNode1(root *TreeNode)*TreeNode{
|
||||
if root.Left==nil{
|
||||
pRight:=root.Right
|
||||
root.Right=nil
|
||||
return pRight
|
||||
}
|
||||
root.Left=deleteNode1(root.Left)
|
||||
return root
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
@ -265,4 +330,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -139,7 +139,32 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```java
|
||||
class Solution {
|
||||
public int findMinArrowShots(int[][] points) {
|
||||
Arrays.sort(points, new Comparator<int[]>() {
|
||||
@Override
|
||||
public int compare(int[] o1, int[] o2) {
|
||||
if (o1[0] != o2[0]) {
|
||||
return Integer.compare(o1[0],o2[0]);
|
||||
} else {
|
||||
return Integer.compare(o1[0],o2[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;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
@ -153,4 +178,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -88,7 +88,36 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
|
||||
Map<Integer, Integer> map = new HashMap<>();
|
||||
int temp;
|
||||
int res = 0;
|
||||
//统计两个数组中的元素之和,同时统计出现的次数,放入map
|
||||
for (int i : nums1) {
|
||||
for (int j : nums2) {
|
||||
temp = i + j;
|
||||
if (map.containsKey(temp)) {
|
||||
map.put(temp, map.get(temp) + 1);
|
||||
} else {
|
||||
map.put(temp, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
//统计剩余的两个元素的和,在map中找是否存在相加为0的情况,同时记录次数
|
||||
for (int i : nums3) {
|
||||
for (int j : nums4) {
|
||||
temp = i + j;
|
||||
if (map.containsKey(0 - temp)) {
|
||||
res += map.get(0 - temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
你有两个孩子和三块小饼干,2个孩子的胃口值分别是1,2。
|
||||
你拥有的饼干数量和尺寸都足以让所有孩子满足。
|
||||
所以你应该输出2.
|
||||
|
||||
|
||||
|
||||
提示:
|
||||
* 1 <= g.length <= 3 * 10^4
|
||||
@ -115,7 +115,23 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public int findContentChildren(int[] g, int[] s) {
|
||||
Arrays.sort(g);
|
||||
Arrays.sort(s);
|
||||
int start = 0;
|
||||
int count = 0;
|
||||
for (int i = 0; i < s.length && start < g.length; i++) {
|
||||
if (s[i] >= g[start]) {
|
||||
start++;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
@ -129,4 +145,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -161,7 +161,33 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
public int findMaxForm(String[] strs, int m, int n) {
|
||||
//dp[i][j]表示i个0和j个1时的最大子集
|
||||
int[][] dp = new int[m + 1][n + 1];
|
||||
int oneNum, zeroNum;
|
||||
for (String str : strs) {
|
||||
oneNum = 0;
|
||||
zeroNum = 0;
|
||||
for (char ch : str.toCharArray()) {
|
||||
if (ch == '0') {
|
||||
zeroNum++;
|
||||
} else {
|
||||
oneNum++;
|
||||
}
|
||||
}
|
||||
//倒序遍历
|
||||
for (int i = m; i >= zeroNum; i--) {
|
||||
for (int j = n; j >= oneNum; j--) {
|
||||
dp[i][j] = Math.max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[m][n];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
@ -200,6 +200,32 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```java
|
||||
class Solution {
|
||||
private List<Integer> path = new ArrayList<>();
|
||||
private List<List<Integer>> res = new ArrayList<>();
|
||||
public List<List<Integer>> findSubsequences(int[] nums) {
|
||||
backtracking(nums,0);
|
||||
return res;
|
||||
}
|
||||
|
||||
private void backtracking (int[] nums, int start) {
|
||||
if (path.size() > 1) {
|
||||
res.add(new ArrayList<>(path));
|
||||
}
|
||||
|
||||
int[] used = new int[201];
|
||||
for (int i = start; i < nums.length; i++) {
|
||||
if (!path.isEmpty() && nums[i] < path.get(path.size() - 1) ||
|
||||
(used[nums[i] + 100] == 1)) continue;
|
||||
used[nums[i] + 100] = 1;
|
||||
path.add(nums[i]);
|
||||
backtracking(nums, i + 1);
|
||||
path.remove(path.size() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Python:
|
||||
@ -207,6 +233,34 @@ Python:
|
||||
|
||||
Go:
|
||||
|
||||
Javascript:
|
||||
|
||||
```Javascript
|
||||
|
||||
var findSubsequences = function(nums) {
|
||||
let result = []
|
||||
let path = []
|
||||
function backtracing(startIndex) {
|
||||
if(path.length > 1) {
|
||||
result.push(path.slice())
|
||||
}
|
||||
let uset = []
|
||||
for(let i = startIndex; i < nums.length; i++) {
|
||||
if((path.length > 0 && nums[i] < path[path.length - 1]) || uset[nums[i] + 100]) {
|
||||
continue
|
||||
}
|
||||
uset[nums[i] + 100] = true
|
||||
path.push(nums[i])
|
||||
backtracing(i + 1)
|
||||
path.pop()
|
||||
}
|
||||
}
|
||||
backtracing(0)
|
||||
return result
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
@ -214,4 +268,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -241,7 +241,24 @@ dp[j] += dp[j - nums[i]];
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public int findTargetSumWays(int[] nums, int target) {
|
||||
int sum = 0;
|
||||
for (int i = 0; i < nums.length; i++) sum += nums[i];
|
||||
if ((target + sum) % 2 != 0) return 0;
|
||||
int size = (target + sum) / 2;
|
||||
int[] dp = new int[size + 1];
|
||||
dp[0] = 1;
|
||||
for (int i = 0; i < nums.length; i++) {
|
||||
for (int j = size; j >= nums[i]; j--) {
|
||||
dp[j] += dp[j - nums[i]];
|
||||
}
|
||||
}
|
||||
return dp[size];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
@ -255,4 +272,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -345,6 +345,53 @@ public:
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
ArrayList<Integer> resList;
|
||||
int maxCount;
|
||||
int count;
|
||||
TreeNode pre;
|
||||
|
||||
public int[] findMode(TreeNode root) {
|
||||
resList = new ArrayList<>();
|
||||
maxCount = 0;
|
||||
count = 0;
|
||||
pre = null;
|
||||
findMode1(root);
|
||||
int[] res = new int[resList.size()];
|
||||
for (int i = 0; i < resList.size(); i++) {
|
||||
res[i] = resList.get(i);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public void findMode1(TreeNode root) {
|
||||
if (root == null) {
|
||||
return;
|
||||
}
|
||||
findMode1(root.left);
|
||||
|
||||
int rootValue = root.val;
|
||||
// 计数
|
||||
if (pre == null || rootValue != pre.val) {
|
||||
count = 1;
|
||||
} else {
|
||||
count++;
|
||||
}
|
||||
// 更新结果以及maxCount
|
||||
if (count > maxCount) {
|
||||
resList.clear();
|
||||
resList.add(rootValue);
|
||||
maxCount = count;
|
||||
} else if (count == maxCount) {
|
||||
resList.add(rootValue);
|
||||
}
|
||||
pre = root;
|
||||
|
||||
findMode1(root.right);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
@ -358,4 +405,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -171,7 +171,20 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
public int fib(int n) {
|
||||
if (n < 2) return n;
|
||||
int a = 0, b = 1, c = 0;
|
||||
for (int i = 1; i < n; i++) {
|
||||
c = a + b;
|
||||
a = b;
|
||||
b = c;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
@ -218,6 +218,60 @@ public:
|
||||
|
||||
Java:
|
||||
|
||||
```java
|
||||
// 递归法
|
||||
class Solution {
|
||||
private int Deep = -1;
|
||||
private int value = 0;
|
||||
public int findBottomLeftValue(TreeNode root) {
|
||||
value = root.val;
|
||||
findLeftValue(root,0);
|
||||
return value;
|
||||
}
|
||||
|
||||
private void findLeftValue (TreeNode root,int deep) {
|
||||
if (root == null) return;
|
||||
if (root.left == null && root.right == null) {
|
||||
if (deep > Deep) {
|
||||
value = root.val;
|
||||
Deep = deep;
|
||||
}
|
||||
}
|
||||
if (root.left != null) findLeftValue(root.left,deep + 1);
|
||||
if (root.right != null) findLeftValue(root.right,deep + 1);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
//迭代法
|
||||
class Solution {
|
||||
|
||||
public int findBottomLeftValue(TreeNode root) {
|
||||
Queue<TreeNode> queue = new LinkedList<>();
|
||||
queue.offer(root);
|
||||
int res = 0;
|
||||
while (!queue.isEmpty()) {
|
||||
int size = queue.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
TreeNode poll = queue.poll();
|
||||
if (i == 0) {
|
||||
res = poll.val;
|
||||
}
|
||||
if (poll.left != null) {
|
||||
queue.offer(poll.left);
|
||||
}
|
||||
if (poll.right != null) {
|
||||
queue.offer(poll.right);
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
Python:
|
||||
|
||||
@ -231,4 +285,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -148,6 +148,25 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```java
|
||||
public class Solution {
|
||||
public int longestPalindromeSubseq(String s) {
|
||||
int len = s.length();
|
||||
int[][] dp = new int[len + 1][len + 1];
|
||||
for (int i = len - 1; i >= 0; i--) { // 从后往前遍历 保证情况不漏
|
||||
dp[i][i] = 1; // 初始化
|
||||
for (int j = i + 1; j < len; j++) {
|
||||
if (s.charAt(i) == s.charAt(j)) {
|
||||
dp[i][j] = dp[i + 1][j - 1] + 2;
|
||||
} else {
|
||||
dp[i][j] = Math.max(dp[i + 1][j], Math.max(dp[i][j], dp[i][j - 1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[0][len - 1];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Python:
|
||||
|
@ -188,7 +188,22 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
public int change(int amount, int[] coins) {
|
||||
//递推表达式
|
||||
int[] dp = new int[amount + 1];
|
||||
//初始化dp数组,表示金额为0时只有一种情况,也就是什么都不装
|
||||
dp[0] = 1;
|
||||
for (int i = 0; i < coins.length; i++) {
|
||||
for (int j = coins[i]; j <= amount; j++) {
|
||||
dp[j] += dp[j - coins[i]];
|
||||
}
|
||||
}
|
||||
return dp[amount];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
@ -152,6 +152,29 @@ public:
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
TreeNode pre;// 记录上一个遍历的结点
|
||||
int result = Integer.MAX_VALUE;
|
||||
public int getMinimumDifference(TreeNode root) {
|
||||
if (root == null) {
|
||||
return result;
|
||||
}
|
||||
// 左
|
||||
int left = getMinimumDifference(root.left);
|
||||
|
||||
// 中
|
||||
if (pre != null) {
|
||||
result = Math.min(left, root.val - pre.val);
|
||||
}
|
||||
pre = root;
|
||||
// 右
|
||||
int right = getMinimumDifference(root.right);
|
||||
result = Math.min(right, result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
@ -165,4 +188,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -173,7 +173,27 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```Java
|
||||
class Solution {
|
||||
int sum;
|
||||
public TreeNode convertBST(TreeNode root) {
|
||||
sum = 0;
|
||||
convertBST1(root);
|
||||
return root;
|
||||
}
|
||||
|
||||
// 按右中左顺序遍历,累加即可
|
||||
public void convertBST1(TreeNode root) {
|
||||
if (root == null) {
|
||||
return;
|
||||
}
|
||||
convertBST1(root.right);
|
||||
sum += root.val;
|
||||
root.val = sum;
|
||||
convertBST1(root.left);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
@ -187,4 +207,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -46,7 +46,7 @@ https://leetcode-cn.com/problems/reverse-string-ii/
|
||||
|
||||
使用C++库函数reverse的版本如下:
|
||||
|
||||
```
|
||||
```C++
|
||||
class Solution {
|
||||
public:
|
||||
string reverseStr(string s, int k) {
|
||||
@ -68,7 +68,8 @@ public:
|
||||
那么我们也可以实现自己的reverse函数,其实和题目[344. 反转字符串](https://mp.weixin.qq.com/s/X02S61WCYiCEhaik6VUpFA)道理是一样的。
|
||||
|
||||
下面我实现的reverse函数区间是左闭右闭区间,代码如下:
|
||||
```
|
||||
|
||||
```C++
|
||||
class Solution {
|
||||
public:
|
||||
void reverse(string& s, int start, int end) {
|
||||
@ -101,7 +102,36 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```Java
|
||||
class Solution {
|
||||
public String reverseStr(String s, int k) {
|
||||
StringBuffer res = new StringBuffer();
|
||||
|
||||
for (int i = 0; i < s.length(); i += (2 * k)) {
|
||||
StringBuffer temp = new StringBuffer();
|
||||
// 剩余字符大于 k 个,每隔 2k 个字符的前 k 个字符进行反转
|
||||
if (i + k <= s.length()) {
|
||||
// 反转前 k 个字符
|
||||
temp.append(s.substring(i, i + k));
|
||||
res.append(temp.reverse());
|
||||
|
||||
// 反转完前 k 个字符之后,如果紧接着还有 k 个字符,则直接加入这 k 个字符
|
||||
if (i + 2 * k <= s.length()) {
|
||||
res.append(s.substring(i + k, i + 2 * k));
|
||||
// 不足 k 个字符,则直接加入剩下所有字符
|
||||
} else {
|
||||
res.append(s.substring(i + k, s.length()));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// 剩余字符少于 k 个,则将剩余字符全部反转。
|
||||
temp.append(s.substring(i, s.length()));
|
||||
res.append(temp.reverse());
|
||||
}
|
||||
return res.toString();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
@ -257,6 +257,59 @@ public:
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
// 递归
|
||||
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
|
||||
if (root1 == null) return root2;
|
||||
if (root2 == null) return root1;
|
||||
|
||||
TreeNode newRoot = new TreeNode(root1.val + root2.val);
|
||||
newRoot.left = mergeTrees(root1.left,root2.left);
|
||||
newRoot.right = mergeTrees(root1.right,root2.right);
|
||||
return newRoot;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
// 迭代
|
||||
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
|
||||
if (root1 == null) {
|
||||
return root2;
|
||||
}
|
||||
if (root2 == null) {
|
||||
return root1;
|
||||
}
|
||||
Stack<TreeNode> stack = new Stack<>();
|
||||
stack.push(root2);
|
||||
stack.push(root1);
|
||||
while (!stack.isEmpty()) {
|
||||
TreeNode node1 = stack.pop();
|
||||
TreeNode node2 = stack.pop();
|
||||
node1.val += node2.val;
|
||||
if (node2.right != null && node1.right != null) {
|
||||
stack.push(node2.right);
|
||||
stack.push(node1.right);
|
||||
} else {
|
||||
if (node1.right == null) {
|
||||
node1.right = node2.right;
|
||||
}
|
||||
}
|
||||
if (node2.left != null && node1.left != null) {
|
||||
stack.push(node2.left);
|
||||
stack.push(node1.left);
|
||||
} else {
|
||||
if (node1.left == null) {
|
||||
node1.left = node2.left;
|
||||
}
|
||||
}
|
||||
}
|
||||
return root1;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
@ -270,4 +323,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -227,6 +227,30 @@ Python:
|
||||
|
||||
|
||||
Go:
|
||||
```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]{
|
||||
if j-i<=1{
|
||||
res++
|
||||
dp[i][j]=true
|
||||
}else if dp[i+1][j-1]{
|
||||
res++
|
||||
dp[i][j]=true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
@ -225,6 +225,35 @@ root->right = traversal(nums, maxValueIndex + 1, right);
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
public TreeNode constructMaximumBinaryTree(int[] nums) {
|
||||
return constructMaximumBinaryTree1(nums, 0, nums.length);
|
||||
}
|
||||
|
||||
public TreeNode constructMaximumBinaryTree1(int[] nums, int leftIndex, int rightIndex) {
|
||||
if (rightIndex - leftIndex < 1) {// 没有元素了
|
||||
return null;
|
||||
}
|
||||
if (rightIndex - leftIndex == 1) {// 只有一个元素
|
||||
return new TreeNode(nums[leftIndex]);
|
||||
}
|
||||
int maxIndex = leftIndex;// 最大值所在位置
|
||||
int maxVal = nums[maxIndex];// 最大值
|
||||
for (int i = leftIndex + 1; i < rightIndex; i++) {
|
||||
if (nums[i] > maxVal){
|
||||
maxVal = nums[i];
|
||||
maxIndex = i;
|
||||
}
|
||||
}
|
||||
TreeNode root = new TreeNode(maxVal);
|
||||
// 根据maxIndex划分左右子树
|
||||
root.left = constructMaximumBinaryTree1(nums, leftIndex, maxIndex);
|
||||
root.right = constructMaximumBinaryTree1(nums, maxIndex + 1, rightIndex);
|
||||
return root;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
@ -238,4 +267,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -243,6 +243,26 @@ public:
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
public TreeNode trimBST(TreeNode root, int low, int high) {
|
||||
if (root == null) {
|
||||
return null;
|
||||
}
|
||||
if (root.val < low) {
|
||||
return trimBST(root.right, low, high);
|
||||
}
|
||||
if (root.val > high) {
|
||||
return trimBST(root.left, low, high);
|
||||
}
|
||||
// root在[low,high]范围内
|
||||
root.left = trimBST(root.left, low, high);
|
||||
root.right = trimBST(root.right, low, high);
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
@ -256,4 +276,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -140,12 +140,99 @@ public:
|
||||
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
// 递归,普通二叉树
|
||||
public TreeNode searchBST(TreeNode root, int val) {
|
||||
if (root == null || root.val == val) {
|
||||
return root;
|
||||
}
|
||||
TreeNode left = searchBST(root.left, val);
|
||||
if (left != null) {
|
||||
return left;
|
||||
}
|
||||
return searchBST(root.right, val);
|
||||
}
|
||||
}
|
||||
|
||||
class Solution {
|
||||
// 递归,利用二叉搜索树特点,优化
|
||||
public TreeNode searchBST(TreeNode root, int val) {
|
||||
if (root == null || root.val == val) {
|
||||
return root;
|
||||
}
|
||||
if (val < root.val) {
|
||||
return searchBST(root.left, val);
|
||||
} else {
|
||||
return searchBST(root.right, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Solution {
|
||||
// 迭代,普通二叉树
|
||||
public TreeNode searchBST(TreeNode root, int val) {
|
||||
if (root == null || root.val == val) {
|
||||
return root;
|
||||
}
|
||||
Stack<TreeNode> stack = new Stack<>();
|
||||
stack.push(root);
|
||||
while (!stack.isEmpty()) {
|
||||
TreeNode pop = stack.pop();
|
||||
if (pop.val == val) {
|
||||
return pop;
|
||||
}
|
||||
if (pop.right != null) {
|
||||
stack.push(pop.right);
|
||||
}
|
||||
if (pop.left != null) {
|
||||
stack.push(pop.left);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class Solution {
|
||||
// 迭代,利用二叉搜索树特点,优化,可以不需要栈
|
||||
public TreeNode searchBST(TreeNode root, int val) {
|
||||
while (root != null)
|
||||
if (val < root.val) root = root.left;
|
||||
else if (val > root.val) root = root.right;
|
||||
else return root;
|
||||
return root;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
递归法:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def searchBST(self, root: TreeNode, val: int) -> TreeNode:
|
||||
if root is None:
|
||||
return None
|
||||
if val < root.val: return self.searchBST(root.left, val)
|
||||
elif val > root.val: return self.searchBST(root.right, val)
|
||||
else: return root
|
||||
```
|
||||
|
||||
迭代法:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def searchBST(self, root: TreeNode, val: int) -> TreeNode:
|
||||
while root is not None:
|
||||
if val < root.val: root = root.left
|
||||
elif val > root.val: root = root.right
|
||||
else: return root
|
||||
return root
|
||||
```
|
||||
|
||||
|
||||
Go:
|
||||
|
||||
@ -156,4 +243,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -16,7 +16,7 @@
|
||||
注意,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。 你可以返回任意有效的结果。
|
||||
|
||||

|
||||
|
||||
|
||||
提示:
|
||||
|
||||
* 给定的树上的节点数介于 0 和 10^4 之间
|
||||
@ -206,12 +206,69 @@ public:
|
||||
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
Java:
|
||||
```java
|
||||
class Solution {
|
||||
public TreeNode insertIntoBST(TreeNode root, int val) {
|
||||
if (root == null) return new TreeNode(val);
|
||||
TreeNode newRoot = root;
|
||||
TreeNode pre = root;
|
||||
while (root != null) {
|
||||
pre = root;
|
||||
if (root.val > val) {
|
||||
root = root.left;
|
||||
} else if (root.val < val) {
|
||||
root = root.right;
|
||||
}
|
||||
}
|
||||
if (pre.val > val) {
|
||||
pre.left = new TreeNode(val);
|
||||
} else {
|
||||
pre.right = new TreeNode(val);
|
||||
}
|
||||
|
||||
return newRoot;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
递归法
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public TreeNode insertIntoBST(TreeNode root, int val) {
|
||||
return buildTree(root, val);
|
||||
}
|
||||
|
||||
public TreeNode buildTree(TreeNode root, int val){
|
||||
if (root == null) // 如果当前节点为空,也就意味着val找到了合适的位置,此时创建节点直接返回。
|
||||
return new TreeNode(val);
|
||||
if (root.val < val){
|
||||
root.right = buildTree(root.right, val); // 递归创建右子树
|
||||
}else if (root.val > val){
|
||||
root.left = buildTree(root.left, val); // 递归创建左子树
|
||||
}
|
||||
return root;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
递归法
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def insertIntoBST(self, root: TreeNode, val: int) -> TreeNode:
|
||||
if root is None:
|
||||
return TreeNode(val) # 如果当前节点为空,也就意味着val找到了合适的位置,此时创建节点直接返回。
|
||||
if root.val < val:
|
||||
root.right = self.insertIntoBST(root.right, val) # 递归创建右子树
|
||||
if root.val > val:
|
||||
root.left = self.insertIntoBST(root.left, val) # 递归创建左子树
|
||||
return root
|
||||
```
|
||||
|
||||
|
||||
Go:
|
||||
|
||||
@ -222,4 +279,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -23,7 +23,7 @@
|
||||
输入: nums = [-1,0,3,5,9,12], target = 2
|
||||
输出: -1
|
||||
解释: 2 不存在 nums 中因此返回 -1
|
||||
|
||||
|
||||
提示:
|
||||
|
||||
* 你可以假设 nums 中的所有元素是不重复的。
|
||||
@ -146,12 +146,67 @@ public:
|
||||
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
(版本一)左闭右闭区间
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public int search(int[] nums, int target) {
|
||||
int left = 0, right = nums.length - 1;
|
||||
while (left <= right) {
|
||||
int mid = left + ((right - left) >> 1);
|
||||
if (nums[mid] == target)
|
||||
return mid;
|
||||
else if (nums[mid] < target)
|
||||
left = mid + 1;
|
||||
else if (nums[mid] > target)
|
||||
right = mid - 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
(版本二)左闭右开区间
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public int search(int[] nums, int target) {
|
||||
int left = 0, right = nums.length;
|
||||
while (left < right) {
|
||||
int mid = left + ((right - left) >> 1);
|
||||
if (nums[mid] == target)
|
||||
return mid;
|
||||
else if (nums[mid] < target)
|
||||
left = mid + 1;
|
||||
else if (nums[mid] > target)
|
||||
right = mid;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python3
|
||||
class Solution:
|
||||
def search(self, nums: List[int], target: int) -> int:
|
||||
left, right = 0, len(nums) - 1
|
||||
|
||||
while left <= right:
|
||||
middle = (left + right) // 2
|
||||
|
||||
if nums[middle] < target:
|
||||
left = middle + 1
|
||||
elif nums[middle] > target:
|
||||
right = middle - 1
|
||||
else:
|
||||
return middle
|
||||
return -1
|
||||
```
|
||||
|
||||
|
||||
Go:
|
||||
|
||||
@ -162,4 +217,4 @@ Go:
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
@ -157,7 +157,78 @@ private:
|
||||
|
||||
|
||||
Java:
|
||||
```Java
|
||||
class MyLinkedList {
|
||||
//size存储链表元素的个数
|
||||
int size;
|
||||
//虚拟头结点
|
||||
ListNode head;
|
||||
|
||||
//初始化链表
|
||||
public MyLinkedList() {
|
||||
size = 0;
|
||||
head = new ListNode(0);
|
||||
}
|
||||
|
||||
//获取第index个节点的数值
|
||||
public int get(int index) {
|
||||
//如果index非法,返回-1
|
||||
if (index < 0 || index >= size) {
|
||||
return -1;
|
||||
}
|
||||
ListNode currentNode = head;
|
||||
//包含一个虚拟头节点,所以查找第 index+1 个节点
|
||||
for (int i = 0; i <= index; i++) {
|
||||
currentNode = currentNode.next;
|
||||
}
|
||||
return currentNode.val;
|
||||
}
|
||||
|
||||
//在链表最前面插入一个节点
|
||||
public void addAtHead(int val) {
|
||||
addAtIndex(0, val);
|
||||
}
|
||||
|
||||
//在链表的最后插入一个节点
|
||||
public void addAtTail(int val) {
|
||||
addAtIndex(size, val);
|
||||
}
|
||||
|
||||
// 在第 index 个节点之前插入一个新节点,例如index为0,那么新插入的节点为链表的新头节点。
|
||||
// 如果 index 等于链表的长度,则说明是新插入的节点为链表的尾结点
|
||||
// 如果 index 大于链表的长度,则返回空
|
||||
public void addAtIndex(int index, int val) {
|
||||
if (index > size) {
|
||||
return;
|
||||
}
|
||||
if (index < 0) {
|
||||
index = 0;
|
||||
}
|
||||
size++;
|
||||
//找到要插入节点的前驱
|
||||
ListNode pred = head;
|
||||
for (int i = 0; i < index; i++) {
|
||||
pred = pred.next;
|
||||
}
|
||||
ListNode toAdd = new ListNode(val);
|
||||
toAdd.next = pred.next;
|
||||
pred.next = toAdd;
|
||||
}
|
||||
|
||||
//删除第index个节点
|
||||
public void deleteAtIndex(int index) {
|
||||
if (index < 0 || index >= size) {
|
||||
return;
|
||||
}
|
||||
size--;
|
||||
ListNode pred = head;
|
||||
for (int i = 0; i < index; i++) {
|
||||
pred = pred.next;
|
||||
}
|
||||
pred.next = pred.next.next;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user