mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-05 14:46:51 +08:00
Update
This commit is contained in:
@ -352,5 +352,86 @@ List<int> twoSum(List<int> nums, int target) {
|
||||
}
|
||||
```
|
||||
|
||||
C:
|
||||
```c
|
||||
|
||||
|
||||
/**
|
||||
* Note: The returned array must be malloced, assume caller calls free().
|
||||
*/
|
||||
|
||||
// leetcode 支持 ut_hash 函式庫
|
||||
|
||||
typedef struct {
|
||||
int key;
|
||||
int value;
|
||||
UT_hash_handle hh; // make this structure hashable
|
||||
} map;
|
||||
|
||||
map* hashMap = NULL;
|
||||
|
||||
void hashMapAdd(int key, int value){
|
||||
map* s;
|
||||
// key already in the hash?
|
||||
HASH_FIND_INT(hashMap, &key, s);
|
||||
if(s == NULL){
|
||||
s = (map*)malloc(sizeof(map));
|
||||
s -> key = key;
|
||||
HASH_ADD_INT(hashMap, key, s);
|
||||
}
|
||||
s -> value = value;
|
||||
}
|
||||
|
||||
map* hashMapFind(int key){
|
||||
map* s;
|
||||
// *s: output pointer
|
||||
HASH_FIND_INT(hashMap, &key, s);
|
||||
return s;
|
||||
}
|
||||
|
||||
void hashMapCleanup(){
|
||||
map* cur, *tmp;
|
||||
HASH_ITER(hh, hashMap, cur, tmp){
|
||||
HASH_DEL(hashMap, cur);
|
||||
free(cur);
|
||||
}
|
||||
}
|
||||
|
||||
void hashPrint(){
|
||||
map* s;
|
||||
for(s = hashMap; s != NULL; s=(map*)(s -> hh.next)){
|
||||
printf("key %d, value %d\n", s -> key, s -> value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int* twoSum(int* nums, int numsSize, int target, int* returnSize){
|
||||
int i, *ans;
|
||||
// hash find result
|
||||
map* hashMapRes;
|
||||
hashMap = NULL;
|
||||
ans = malloc(sizeof(int) * 2);
|
||||
|
||||
for(i = 0; i < numsSize; i++){
|
||||
// key 代表 nums[i] 的值,value 代表所在 index;
|
||||
hashMapAdd(nums[i], i);
|
||||
}
|
||||
|
||||
hashPrint();
|
||||
|
||||
for(i = 0; i < numsSize; i++){
|
||||
hashMapRes = hashMapFind(target - nums[i]);
|
||||
if(hashMapRes && hashMapRes -> value != i){
|
||||
ans[0] = i;
|
||||
ans[1] = hashMapRes -> value ;
|
||||
*returnSize = 2;
|
||||
return ans;
|
||||
}
|
||||
}
|
||||
|
||||
hashMapCleanup();
|
||||
return NULL;
|
||||
}
|
||||
```
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -75,7 +75,12 @@ public:
|
||||
fast = fast->next;
|
||||
slow = slow->next;
|
||||
}
|
||||
slow->next = slow->next->next;
|
||||
slow->next = slow->next->next;
|
||||
|
||||
// ListNode *tmp = slow->next; C++释放内存的逻辑
|
||||
// slow->next = tmp->next;
|
||||
// delete nth;
|
||||
|
||||
return dummyHead->next;
|
||||
}
|
||||
};
|
||||
@ -87,30 +92,27 @@ public:
|
||||
java:
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public ListNode removeNthFromEnd(ListNode head, int n) {
|
||||
ListNode dummy = new ListNode(-1);
|
||||
dummy.next = head;
|
||||
public ListNode removeNthFromEnd(ListNode head, int n){
|
||||
ListNode dummyNode = new ListNode(0);
|
||||
dummyNode.next = head;
|
||||
|
||||
ListNode slow = dummy;
|
||||
ListNode fast = dummy;
|
||||
while (n-- > 0) {
|
||||
fast = fast.next;
|
||||
}
|
||||
// 记住 待删除节点slow 的上一节点
|
||||
ListNode prev = null;
|
||||
while (fast != null) {
|
||||
prev = slow;
|
||||
slow = slow.next;
|
||||
fast = fast.next;
|
||||
}
|
||||
// 上一节点的next指针绕过 待删除节点slow 直接指向slow的下一节点
|
||||
prev.next = slow.next;
|
||||
// 释放 待删除节点slow 的next指针, 这句删掉也能AC
|
||||
slow.next = null;
|
||||
ListNode fastIndex = dummyNode;
|
||||
ListNode slowIndex = dummyNode;
|
||||
|
||||
return dummy.next;
|
||||
//只要快慢指针相差 n 个结点即可
|
||||
for (int i = 0; i < n ; i++){
|
||||
fastIndex = fastIndex.next;
|
||||
}
|
||||
|
||||
while (fastIndex.next != null){
|
||||
fastIndex = fastIndex.next;
|
||||
slowIndex = slowIndex.next;
|
||||
}
|
||||
|
||||
//此时 slowIndex 的位置就是待删除元素的前一个位置。
|
||||
//具体情况可自己画一个链表长度为 3 的图来模拟代码来理解
|
||||
slowIndex.next = slowIndex.next.next;
|
||||
return dummyNode.next;
|
||||
}
|
||||
```
|
||||
|
||||
@ -341,5 +343,28 @@ object Solution {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Rust:
|
||||
```rust
|
||||
impl Solution {
|
||||
pub fn remove_nth_from_end(head: Option<Box<ListNode>>, mut n: i32) -> Option<Box<ListNode>> {
|
||||
let mut dummy_head = Box::new(ListNode::new(0));
|
||||
dummy_head.next = head;
|
||||
let mut fast = &dummy_head.clone();
|
||||
let mut slow = &mut dummy_head;
|
||||
while n > 0 {
|
||||
fast = fast.next.as_ref().unwrap();
|
||||
n -= 1;
|
||||
}
|
||||
while fast.next.is_some() {
|
||||
fast = fast.next.as_ref().unwrap();
|
||||
slow = slow.next.as_mut().unwrap();
|
||||
}
|
||||
slow.next = slow.next.as_mut().unwrap().next.take();
|
||||
dummy_head.next
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -380,5 +380,51 @@ function swapPairs($head)
|
||||
}
|
||||
```
|
||||
|
||||
Rust:
|
||||
|
||||
```rust
|
||||
// 虚拟头节点
|
||||
impl Solution {
|
||||
pub fn swap_pairs(head: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
|
||||
let mut dummy_head = Box::new(ListNode::new(0));
|
||||
dummy_head.next = head;
|
||||
let mut cur = dummy_head.as_mut();
|
||||
while let Some(mut node) = cur.next.take() {
|
||||
if let Some(mut next) = node.next.take() {
|
||||
node.next = next.next.take();
|
||||
next.next = Some(node);
|
||||
cur.next = Some(next);
|
||||
cur = cur.next.as_mut().unwrap().next.as_mut().unwrap();
|
||||
} else {
|
||||
cur.next = Some(node);
|
||||
cur = cur.next.as_mut().unwrap();
|
||||
}
|
||||
}
|
||||
dummy_head.next
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```rust
|
||||
// 递归
|
||||
impl Solution {
|
||||
pub fn swap_pairs(head: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
|
||||
if head == None || head.as_ref().unwrap().next == None {
|
||||
return head;
|
||||
}
|
||||
|
||||
let mut node = head.unwrap();
|
||||
|
||||
if let Some(mut next) = node.next.take() {
|
||||
node.next = Solution::swap_pairs(next.next);
|
||||
next.next = Some(node);
|
||||
Some(next)
|
||||
} else {
|
||||
Some(node)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -429,7 +429,57 @@ function searchInsert($nums, $target)
|
||||
return $r + 1;
|
||||
}
|
||||
```
|
||||
|
||||
### C
|
||||
```c
|
||||
//版本一 [left, right]左闭右闭区间
|
||||
int searchInsert(int* nums, int numsSize, int target){
|
||||
//左闭右开区间 [0 , numsSize-1]
|
||||
int left =0;
|
||||
int mid =0;
|
||||
int right = numsSize - 1;
|
||||
while(left <= right){//左闭右闭区间 所以可以 left == right
|
||||
mid = left + (right - left) / 2;
|
||||
if(target < nums[mid]){
|
||||
//target 在左区间 [left, mid - 1]中,原区间包含mid,右区间边界可以向左内缩
|
||||
right = mid -1;
|
||||
}else if( target > nums[mid]){
|
||||
//target 在右区间 [mid + 1, right]中,原区间包含mid,左区间边界可以向右内缩
|
||||
left = mid + 1;
|
||||
}else {
|
||||
// nums[mid] == target ,顺利找到target,直接返回mid
|
||||
return mid;
|
||||
}
|
||||
}
|
||||
//数组中未找到target元素
|
||||
//target在数组所有元素之后,[left, right]是右闭区间,需要返回 right +1
|
||||
return right + 1;
|
||||
}
|
||||
```
|
||||
```c
|
||||
//版本二 [left, right]左闭右开区间
|
||||
int searchInsert(int* nums, int numsSize, int target){
|
||||
//左闭右开区间 [0 , numsSize)
|
||||
int left =0;
|
||||
int mid =0;
|
||||
int right = numsSize;
|
||||
while(left < right){//左闭右闭区间 所以 left < right
|
||||
mid = left + (right - left) / 2;
|
||||
if(target < nums[mid]){
|
||||
//target 在左区间 [left, mid)中,原区间没有包含mid,右区间边界不能内缩
|
||||
right = mid ;
|
||||
}else if( target > nums[mid]){
|
||||
// target 在右区间 [mid+1, right)中,原区间包含mid,左区间边界可以向右内缩
|
||||
left = mid + 1;
|
||||
}else {
|
||||
// nums[mid] == target ,顺利找到target,直接返回mid
|
||||
return mid;
|
||||
}
|
||||
}
|
||||
//数组中未找到target元素
|
||||
//target在数组所有元素之后,[left, right)是右开区间, return right即可
|
||||
return right;
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -214,7 +214,26 @@ class Solution:
|
||||
return ans
|
||||
```
|
||||
|
||||
```python
|
||||
# 贪心版本二
|
||||
class Solution:
|
||||
def jump(self, nums: List[int]) -> int:
|
||||
if len(nums) == 1:
|
||||
return 0
|
||||
curDistance, nextDistance = 0, 0
|
||||
step = 0
|
||||
for i in range(len(nums)-1):
|
||||
nextDistance = max(nextDistance, nums[i]+i)
|
||||
if i == curDistance:
|
||||
curDistance = nextDistance
|
||||
step += 1
|
||||
return step
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Go
|
||||
|
||||
```Go
|
||||
func jump(nums []int) int {
|
||||
dp := make([]int, len(nums))
|
||||
@ -240,7 +259,71 @@ func min(a, b int) int {
|
||||
}
|
||||
```
|
||||
|
||||
```go
|
||||
// 贪心版本一
|
||||
func jump(nums []int) int {
|
||||
n := len(nums)
|
||||
if n == 1 {
|
||||
return 0
|
||||
}
|
||||
cur, next := 0, 0
|
||||
step := 0
|
||||
for i := 0; i < n; i++ {
|
||||
next = max(nums[i]+i, next)
|
||||
if i == cur {
|
||||
if cur != n-1 {
|
||||
step++
|
||||
cur = next
|
||||
if cur >= n-1 {
|
||||
return step
|
||||
}
|
||||
} else {
|
||||
return step
|
||||
}
|
||||
}
|
||||
}
|
||||
return step
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
```
|
||||
|
||||
```go
|
||||
// 贪心版本二
|
||||
func jump(nums []int) int {
|
||||
n := len(nums)
|
||||
if n == 1 {
|
||||
return 0
|
||||
}
|
||||
cur, next := 0, 0
|
||||
step := 0
|
||||
for i := 0; i < n-1; i++ {
|
||||
next = max(nums[i]+i, next)
|
||||
if i == cur {
|
||||
cur = next
|
||||
step++
|
||||
}
|
||||
}
|
||||
return step
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Javascript
|
||||
|
||||
```Javascript
|
||||
var jump = function(nums) {
|
||||
let curIndex = 0
|
||||
|
@ -139,7 +139,31 @@ func canJUmp(nums []int) bool {
|
||||
}
|
||||
```
|
||||
|
||||
```go
|
||||
// 贪心
|
||||
func canJump(nums []int) bool {
|
||||
cover := 0
|
||||
n := len(nums)-1
|
||||
for i := 0; i <= cover; i++ { // 每次与覆盖值比较
|
||||
cover = max(i+nums[i], cover) //每走一步都将 cover 更新为最大值
|
||||
if cover >= n {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
func max(a, b int ) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Javascript
|
||||
|
||||
```Javascript
|
||||
var canJump = function(nums) {
|
||||
if(nums.length === 1) return true
|
||||
|
@ -362,7 +362,33 @@ function minDistance(word1: string, word2: string): number {
|
||||
};
|
||||
```
|
||||
|
||||
C:
|
||||
|
||||
|
||||
```c
|
||||
int min(int num1, int num2, int num3) {
|
||||
return num1 > num2 ? (num2 > num3 ? num3 : num2) : (num1 > num3 ? num3 : num1);
|
||||
}
|
||||
|
||||
int minDistance(char * word1, char * word2){
|
||||
int dp[strlen(word1)+1][strlen(word2)+1];
|
||||
dp[0][0] = 0;
|
||||
for (int i = 1; i <= strlen(word1); i++) dp[i][0] = i;
|
||||
for (int i = 1; i <= strlen(word2); i++) dp[0][i] = i;
|
||||
|
||||
for (int i = 1; i <= strlen(word1); i++) {
|
||||
for (int j = 1; j <= strlen(word2); j++) {
|
||||
if (word1[i-1] == word2[j-1]) {
|
||||
dp[i][j] = dp[i-1][j-1];
|
||||
}
|
||||
else {
|
||||
dp[i][j] = min(dp[i-1][j-1], dp[i][j-1], dp[i-1][j]) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[strlen(word1)][strlen(word2)];
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -367,6 +367,39 @@ function subsetsWithDup(nums: number[]): number[][] {
|
||||
};
|
||||
```
|
||||
|
||||
set去重版本:
|
||||
```typescript
|
||||
// 使用set去重版本
|
||||
function subsetsWithDup(nums: number[]): number[][] {
|
||||
const result: number[][] = [];
|
||||
const path: number[] = [];
|
||||
// 去重之前先排序
|
||||
nums.sort((a, b) => a - b);
|
||||
function backTracking(startIndex: number) {
|
||||
// 收集结果
|
||||
result.push([...path])
|
||||
// 此处不返回也可以因为,每次递归都会使startIndex + 1,当这个数大到nums.length的时候就不会进入递归了。
|
||||
if (startIndex === nums.length) {
|
||||
return
|
||||
}
|
||||
// 定义每一个树层的set集合
|
||||
const set: Set<number> = new Set()
|
||||
for (let i = startIndex; i < nums.length; i++) {
|
||||
// 去重
|
||||
if (set.has(nums[i])) {
|
||||
continue
|
||||
}
|
||||
set.add(nums[i])
|
||||
path.push(nums[i])
|
||||
backTracking(i + 1)
|
||||
// 回溯
|
||||
path.pop()
|
||||
}
|
||||
}
|
||||
backTracking(0)
|
||||
return result
|
||||
};
|
||||
```
|
||||
### Rust
|
||||
|
||||
```Rust
|
||||
|
@ -313,6 +313,31 @@ class solution {
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
/**
|
||||
* 递归法(求深度法)
|
||||
*/
|
||||
//定义最大深度
|
||||
int maxnum = 0;
|
||||
|
||||
public int maxDepth(TreeNode root) {
|
||||
ans(root,0);
|
||||
return maxnum;
|
||||
}
|
||||
|
||||
//递归求解最大深度
|
||||
void ans(TreeNode tr,int tmp){
|
||||
if(tr==null) return;
|
||||
tmp++;
|
||||
maxnum = maxnum<tmp?tmp:maxnum;
|
||||
ans(tr.left,tmp);
|
||||
ans(tr.right,tmp);
|
||||
tmp--;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
class solution {
|
||||
/**
|
||||
@ -552,6 +577,29 @@ func maxdepth(root *treenode) int {
|
||||
|
||||
```
|
||||
|
||||
### 559. n叉树的最大深度
|
||||
|
||||
```go
|
||||
func maxDepth(root *Node) int {
|
||||
if root == nil {
|
||||
return 0
|
||||
}
|
||||
q := list.New()
|
||||
q.PushBack(root)
|
||||
depth := 0
|
||||
for q.Len() > 0 {
|
||||
n := q.Len()
|
||||
for i := 0; i < n; i++ {
|
||||
node := q.Remove(q.Front()).(*Node)
|
||||
for j := range node.Children {
|
||||
q.PushBack(node.Children[j])
|
||||
}
|
||||
}
|
||||
depth++
|
||||
}
|
||||
return depth
|
||||
}
|
||||
```
|
||||
|
||||
## javascript
|
||||
|
||||
|
@ -320,8 +320,11 @@ TypeScript:
|
||||
```typescript
|
||||
function sumNumbers(root: TreeNode | null): number {
|
||||
if (root === null) return 0;
|
||||
// 记录最终结果
|
||||
let resTotal: number = 0;
|
||||
// 记录路径中遇到的节点值
|
||||
const route: number[] = [];
|
||||
// 递归初始值
|
||||
route.push(root.val);
|
||||
recur(root, route);
|
||||
return resTotal;
|
||||
@ -342,6 +345,7 @@ function sumNumbers(root: TreeNode | null): number {
|
||||
};
|
||||
}
|
||||
function listToSum(nums: number[]): number {
|
||||
// 数组求和
|
||||
return Number(nums.join(''));
|
||||
}
|
||||
};
|
||||
|
@ -344,6 +344,21 @@ func wordBreak(s string,wordDict []string) bool {
|
||||
}
|
||||
return dp[len(s)]
|
||||
}
|
||||
// 转化为 求装满背包s的前几位字符的方式有几种
|
||||
func wordBreak(s string, wordDict []string) bool {
|
||||
// 装满背包s的前几位字符的方式有几种
|
||||
dp := make([]int, len(s)+1)
|
||||
dp[0] = 1
|
||||
for i := 0; i <= len(s); i++ { // 背包
|
||||
for j := 0; j < len(wordDict); j++ { // 物品
|
||||
if i >= len(wordDict[j]) && wordDict[j] == s[i-len(wordDict[j]):i] {
|
||||
dp[i] += dp[i-len(wordDict[j])]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dp[len(s)] > 0
|
||||
}
|
||||
```
|
||||
|
||||
Javascript:
|
||||
|
@ -89,7 +89,12 @@ C++代码如下:
|
||||
class Solution {
|
||||
public:
|
||||
int evalRPN(vector<string>& tokens) {
|
||||
<<<<<<< HEAD
|
||||
stack<long long> st;
|
||||
=======
|
||||
// 力扣修改了后台测试数据,需要用longlong
|
||||
stack<long long> st;
|
||||
>>>>>>> 28f3b52a82e3cc650290fb02030a53900e122f43
|
||||
for (int i = 0; i < tokens.size(); i++) {
|
||||
if (tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/") {
|
||||
long long num1 = st.top();
|
||||
@ -104,11 +109,13 @@ public:
|
||||
st.push(stoll(tokens[i]));
|
||||
}
|
||||
}
|
||||
|
||||
int result = st.top();
|
||||
st.pop(); // 把栈里最后一个元素弹出(其实不弹出也没事)
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
## 题外话
|
||||
|
@ -360,6 +360,75 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
/*
|
||||
* 解法四:时间复杂度 O(n)
|
||||
* 参考卡哥 c++ 代码的三步骤:先移除多余空格,再将整个字符串反转,最后把单词逐个反转
|
||||
* 有别于解法一 :没有用 StringBuilder 实现,而是对 String 的 char[] 数组操作来实现以上三个步骤
|
||||
*/
|
||||
class Solution {
|
||||
//用 char[] 来实现 String 的 removeExtraSpaces,reverse 操作
|
||||
public String reverseWords(String s) {
|
||||
char[] chars = s.toCharArray();
|
||||
//1.去除首尾以及中间多余空格
|
||||
chars = removeExtraSpaces(chars);
|
||||
//2.整个字符串反转
|
||||
reverse(chars, 0, chars.length - 1);
|
||||
//3.单词反转
|
||||
reverseEachWord(chars);
|
||||
return new String(chars);
|
||||
}
|
||||
|
||||
//1.用 快慢指针 去除首尾以及中间多余空格,可参考数组元素移除的题解
|
||||
public char[] removeExtraSpaces(char[] chars) {
|
||||
int slow = 0;
|
||||
for (int fast = 0; fast < chars.length; fast++) {
|
||||
//先用 fast 移除所有空格
|
||||
if (chars[fast] != ' ') {
|
||||
//在用 slow 加空格。 除第一个单词外,单词末尾要加空格
|
||||
if (slow != 0)
|
||||
chars[slow++] = ' ';
|
||||
//fast 遇到空格或遍历到字符串末尾,就证明遍历完一个单词了
|
||||
while (fast < chars.length && chars[fast] != ' ')
|
||||
chars[slow++] = chars[fast++];
|
||||
}
|
||||
}
|
||||
//相当于 c++ 里的 resize()
|
||||
char[] newChars = new char[slow];
|
||||
System.arraycopy(chars, 0, newChars, 0, slow);
|
||||
return newChars;
|
||||
}
|
||||
|
||||
//双指针实现指定范围内字符串反转,可参考字符串反转题解
|
||||
public void reverse(char[] chars, int left, int right) {
|
||||
if (right >= chars.length) {
|
||||
System.out.println("set a wrong right");
|
||||
return;
|
||||
}
|
||||
while (left < right) {
|
||||
chars[left] ^= chars[right];
|
||||
chars[right] ^= chars[left];
|
||||
chars[left] ^= chars[right];
|
||||
left++;
|
||||
right--;
|
||||
}
|
||||
}
|
||||
|
||||
//3.单词反转
|
||||
public void reverseEachWord(char[] chars) {
|
||||
int start = 0;
|
||||
//end <= s.length() 这里的 = ,是为了让 end 永远指向单词末尾后一个位置,这样 reverse 的实参更好设置
|
||||
for (int end = 0; end <= chars.length; end++) {
|
||||
// end 每次到单词末尾后的空格或串尾,开始反转单词
|
||||
if (end == chars.length || chars[end] == ' ') {
|
||||
reverse(chars, start, end - 1);
|
||||
start = end + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
python:
|
||||
|
||||
```Python
|
||||
|
@ -588,5 +588,45 @@ object Solution {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Rust:
|
||||
双指针法:
|
||||
|
||||
```rust
|
||||
impl Solution {
|
||||
pub fn reverse_list(head: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
|
||||
let mut cur = head;
|
||||
let mut pre = None;
|
||||
while let Some(mut node) = cur.take() {
|
||||
cur = node.next;
|
||||
node.next = pre;
|
||||
pre = Some(node);
|
||||
}
|
||||
pre
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
递归法:
|
||||
|
||||
```rust
|
||||
impl Solution {
|
||||
pub fn reverse_list(head: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
|
||||
fn rev(
|
||||
mut head: Option<Box<ListNode>>,
|
||||
mut pre: Option<Box<ListNode>>,
|
||||
) -> Option<Box<ListNode>> {
|
||||
if let Some(mut node) = head.take() {
|
||||
let cur = node.next;
|
||||
node.next = pre;
|
||||
pre = Some(node);
|
||||
return rev(cur, pre);
|
||||
}
|
||||
pre
|
||||
}
|
||||
rev(head, None)
|
||||
}
|
||||
}
|
||||
```
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -181,23 +181,23 @@ class Solution:
|
||||
index += 1
|
||||
return 0 if res==float("inf") else res
|
||||
```
|
||||
```python3
|
||||
#滑动窗口
|
||||
```python
|
||||
# 滑动窗口
|
||||
class Solution:
|
||||
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
|
||||
if nums is None or len(nums)==0:
|
||||
if nums is None or len(nums) == 0:
|
||||
return 0
|
||||
lenf=len(nums)+1
|
||||
total=0
|
||||
i=j=0
|
||||
while (j<len(nums)):
|
||||
total=total+nums[j]
|
||||
j+=1
|
||||
while (total>=target):
|
||||
lenf=min(lenf,j-i)
|
||||
total=total-nums[i]
|
||||
i+=1
|
||||
if lenf==len(nums)+1:
|
||||
lenf = len(nums) + 1
|
||||
total = 0
|
||||
i = j = 0
|
||||
while (j < len(nums)):
|
||||
total = total + nums[j]
|
||||
j += 1
|
||||
while (total >= target):
|
||||
lenf = min(lenf, j - i)
|
||||
total = total - nums[i]
|
||||
i += 1
|
||||
if lenf == len(nums) + 1:
|
||||
return 0
|
||||
else:
|
||||
return lenf
|
||||
|
@ -437,6 +437,33 @@ func countNodes(root *TreeNode) int {
|
||||
}
|
||||
```
|
||||
|
||||
迭代法
|
||||
|
||||
```go
|
||||
func countNodes(root *TreeNode) int {
|
||||
if root == nil {
|
||||
return 0
|
||||
}
|
||||
q := list.New()
|
||||
q.PushBack(root)
|
||||
res := 0
|
||||
for q.Len() > 0 {
|
||||
n := q.Len()
|
||||
for i := 0; i < n; i++ {
|
||||
node := q.Remove(q.Front()).(*TreeNode)
|
||||
if node.Left != nil {
|
||||
q.PushBack(node.Left)
|
||||
}
|
||||
if node.Right != nil {
|
||||
q.PushBack(node.Right)
|
||||
}
|
||||
res++
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## JavaScript:
|
||||
|
@ -292,6 +292,40 @@ class MyStack {
|
||||
}
|
||||
```
|
||||
|
||||
优化,使用一个 Queue 实现
|
||||
```java
|
||||
class MyStack {
|
||||
|
||||
Queue<Integer> queue;
|
||||
|
||||
public MyStack() {
|
||||
queue = new LinkedList<>();
|
||||
}
|
||||
|
||||
//每 offer 一个数(A)进来,都重新排列,把这个数(A)放到队列的队首
|
||||
public void push(int x) {
|
||||
queue.offer(x);
|
||||
int size = queue.size();
|
||||
//移动除了 A 的其它数
|
||||
while (size-- > 1)
|
||||
queue.offer(queue.poll());
|
||||
}
|
||||
|
||||
public int pop() {
|
||||
return queue.poll();
|
||||
}
|
||||
|
||||
public int top() {
|
||||
return queue.peek();
|
||||
}
|
||||
|
||||
public boolean empty() {
|
||||
return queue.isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
|
@ -274,6 +274,7 @@ function findContentChildren(g: number[], s: number[]): number {
|
||||
### C
|
||||
|
||||
```c
|
||||
///小餅乾先餵飽小胃口的
|
||||
int cmp(int* a, int* b) {
|
||||
return *a - *b;
|
||||
}
|
||||
@ -296,6 +297,33 @@ int findContentChildren(int* g, int gSize, int* s, int sSize){
|
||||
}
|
||||
```
|
||||
|
||||
```c
|
||||
///大餅乾先餵飽大胃口的
|
||||
int cmp(int* a, int* b) {
|
||||
return *a - *b;
|
||||
}
|
||||
|
||||
int findContentChildren(int* g, int gSize, int* s, int sSize){
|
||||
if(sSize == 0)
|
||||
return 0;
|
||||
|
||||
//将两个数组排序为升序
|
||||
qsort(g, gSize, sizeof(int), cmp);
|
||||
qsort(s, sSize, sizeof(int), cmp);
|
||||
|
||||
int count = 0;
|
||||
int start = sSize - 1;
|
||||
|
||||
for(int i = gSize - 1; i >= 0; i--) {
|
||||
if(start >= 0 && s[start] >= g[i] ) {
|
||||
start--;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
```
|
||||
|
||||
### Scala
|
||||
|
||||
```scala
|
||||
|
@ -47,6 +47,8 @@ dp[i][j]:以i-1为结尾的字符串word1,和以j-1位结尾的字符串word
|
||||
|
||||
那最后当然是取最小值,所以当word1[i - 1] 与 word2[j - 1]不相同的时候,递推公式:dp[i][j] = min({dp[i - 1][j - 1] + 2, dp[i - 1][j] + 1, dp[i][j - 1] + 1});
|
||||
|
||||
因为dp[i - 1][j - 1] + 1等于 dp[i - 1][j] 或 dp[i][j - 1],所以递推公式可简化为:dp[i][j] = min(dp[i - 1][j] + 1, dp[i][j - 1] + 1);
|
||||
|
||||
|
||||
3. dp数组如何初始化
|
||||
|
||||
@ -90,7 +92,7 @@ public:
|
||||
if (word1[i - 1] == word2[j - 1]) {
|
||||
dp[i][j] = dp[i - 1][j - 1];
|
||||
} else {
|
||||
dp[i][j] = min({dp[i - 1][j - 1] + 2, dp[i - 1][j] + 1, dp[i][j - 1] + 1});
|
||||
dp[i][j] = min(dp[i - 1][j] + 1, dp[i][j - 1] + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1240,6 +1240,94 @@ class MyLinkedList() {
|
||||
}
|
||||
```
|
||||
|
||||
Rust:
|
||||
|
||||
```rust
|
||||
#[derive(Debug)]
|
||||
pub struct MyLinkedList {
|
||||
pub val: i32,
|
||||
pub next: Option<Box<MyLinkedList>>,
|
||||
}
|
||||
|
||||
impl MyLinkedList {
|
||||
fn new() -> Self {
|
||||
// 增加头节点
|
||||
MyLinkedList { val: 0, next: None }
|
||||
}
|
||||
|
||||
fn get(&self, index: i32) -> i32 {
|
||||
if index < 0 {
|
||||
return -1;
|
||||
}
|
||||
let mut i = 0;
|
||||
let mut cur = &self.next;
|
||||
while let Some(node) = cur {
|
||||
if i == index {
|
||||
return node.val;
|
||||
}
|
||||
i += 1;
|
||||
cur = &node.next;
|
||||
}
|
||||
-1
|
||||
}
|
||||
|
||||
fn add_at_head(&mut self, val: i32) {
|
||||
let new_node = Box::new(MyLinkedList {
|
||||
val,
|
||||
next: self.next.take(),
|
||||
});
|
||||
self.next = Some(new_node);
|
||||
}
|
||||
|
||||
fn add_at_tail(&mut self, val: i32) {
|
||||
let new_node = Box::new(MyLinkedList { val, next: None });
|
||||
let mut last_node = &mut self.next;
|
||||
while let Some(node) = last_node {
|
||||
last_node = &mut node.next;
|
||||
}
|
||||
*last_node = Some(new_node);
|
||||
}
|
||||
|
||||
fn add_at_index(&mut self, index: i32, val: i32) {
|
||||
if index <= 0 {
|
||||
self.add_at_head(val);
|
||||
} else {
|
||||
let mut i = 0;
|
||||
let mut cur = &mut self.next;
|
||||
while let Some(node) = cur {
|
||||
if i + 1 == index {
|
||||
let new_node = Box::new(MyLinkedList {
|
||||
val,
|
||||
next: node.next.take(),
|
||||
});
|
||||
node.next = Some(new_node);
|
||||
break;
|
||||
}
|
||||
i += 1;
|
||||
cur = &mut node.next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn delete_at_index(&mut self, index: i32) {
|
||||
if index < 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut i = 0;
|
||||
let mut cur = self;
|
||||
while let Some(node) = cur.next.take() {
|
||||
if i == index {
|
||||
cur.next = node.next;
|
||||
break;
|
||||
}
|
||||
i += 1;
|
||||
cur.next = Some(node);
|
||||
cur = cur.next.as_mut().unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -43,7 +43,7 @@
|
||||
|
||||
是不是感觉和昨天讲解的[416. 分割等和子集](https://programmercarl.com/0416.分割等和子集.html)非常像了。
|
||||
|
||||
本题物品的重量为store[i],物品的价值也为store[i]。
|
||||
本题物品的重量为stones[i],物品的价值也为stones[i]。
|
||||
|
||||
对应着01背包里的物品重量weight[i]和 物品价值value[i]。
|
||||
|
||||
|
@ -156,20 +156,20 @@ char* replaceSpace(char* s){
|
||||
Java:
|
||||
```Java
|
||||
//使用一个新的对象,复制 str,复制的过程对其判断,是空格则替换,否则直接复制,类似于数组复制
|
||||
public static String replaceSpace(StringBuffer str) {
|
||||
if (str == null) {
|
||||
public static String replaceSpace(String s) {
|
||||
if (s == null) {
|
||||
return null;
|
||||
}
|
||||
//选用 StringBuilder 单线程使用,比较快,选不选都行
|
||||
//选用 StringBuilder 单线程使用,比较快,选不选都行
|
||||
StringBuilder sb = new StringBuilder();
|
||||
//使用 sb 逐个复制 str ,碰到空格则替换,否则直接复制
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
//str.charAt(i) 为 char 类型,为了比较需要将其转为和 " " 相同的字符串类型
|
||||
//if (" ".equals(String.valueOf(str.charAt(i)))){
|
||||
//使用 sb 逐个复制 s ,碰到空格则替换,否则直接复制
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
//s.charAt(i) 为 char 类型,为了比较需要将其转为和 " " 相同的字符串类型
|
||||
//if (" ".equals(String.valueOf(s.charAt(i)))){}
|
||||
if (s.charAt(i) == ' ') {
|
||||
sb.append("%20");
|
||||
} else {
|
||||
sb.append(str.charAt(i));
|
||||
sb.append(s.charAt(i));
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
|
@ -115,6 +115,29 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
//解法二:空间复杂度:O(1)。用原始数组来进行反转操作
|
||||
//思路为:先整个字符串反转,再反转前面的,最后反转后面 n 个
|
||||
class Solution {
|
||||
public String reverseLeftWords(String s, int n) {
|
||||
char[] chars = s.toCharArray();
|
||||
reverse(chars, 0, chars.length - 1);
|
||||
reverse(chars, 0, chars.length - 1 - n);
|
||||
reverse(chars, chars.length - n, chars.length - 1);
|
||||
return new String(chars);
|
||||
}
|
||||
|
||||
public void reverse(char[] chars, int left, int right) {
|
||||
while (left < right) {
|
||||
chars[left] ^= chars[right];
|
||||
chars[right] ^= chars[left];
|
||||
chars[left] ^= chars[right];
|
||||
left++;
|
||||
right--;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
python:
|
||||
|
||||
```python
|
||||
|
@ -42,7 +42,7 @@ for (int i = 0; i < array.size(); i++) {
|
||||
|
||||
**其实很多数组(字符串)填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作。**
|
||||
|
||||
那么在[字符串:花式反转还不够!](https://programmercarl.com/0151.翻转字符串里的单词.html)中,我们使用双指针法,用O(n)的时间复杂度完成字符串删除类的操作,因为题目要产出冗余空格。
|
||||
那么在[字符串:花式反转还不够!](https://programmercarl.com/0151.翻转字符串里的单词.html)中,我们使用双指针法,用O(n)的时间复杂度完成字符串删除类的操作,因为题目要删除冗余空格。
|
||||
|
||||
**在删除冗余空格的过程中,如果不注意代码效率,很容易写成了O(n^2)的时间复杂度。其实使用双指针法O(n)就可以搞定。**
|
||||
|
||||
|
@ -218,6 +218,22 @@ class ListNode(_x: Int = 0, _next: ListNode = null) {
|
||||
}
|
||||
```
|
||||
|
||||
Rust:
|
||||
```rust
|
||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||
pub struct ListNode<T> {
|
||||
pub val: T,
|
||||
pub next: Option<Box<ListNode<T>>>,
|
||||
}
|
||||
|
||||
impl<T> ListNode<T> {
|
||||
#[inline]
|
||||
fn new(val: T, node: Option<Box<ListNode<T>>>) -> Self {
|
||||
ListNode { next: node, val }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
Reference in New Issue
Block a user