Merge branch 'main' into main

pull/42/head
算法基地 2021-07-29 11:44:45 +08:00 committed by GitHub
commit 2072380477
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
54 changed files with 1359 additions and 190 deletions

View File

@ -3,8 +3,6 @@ name: Restructure files
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
workflow_dispatch:
jobs:

View File

@ -28,7 +28,7 @@
JAVA
JAVA []()
@ -43,7 +43,7 @@
star
.
>
>
@ -153,7 +153,7 @@
- [leetcode 27 ](https://github.com/chefyuan/algorithm-base/blob/main/animation-simulation/%E6%95%B0%E7%BB%84%E7%AF%87/leetcode27%E7%A7%BB%E9%99%A4%E5%85%83%E7%B4%A0.md)
- [leetcode 209 ](https://github.com/chefyuan/algorithm-base/blob/main/animation-simulation/%E6%95%B0%E7%BB%84%E7%AF%87/%E9%95%BF%E5%BA%A6%E6%9C%80%E5%B0%8F%E7%9A%84%E5%AD%90%E6%95%B0%E7%BB%84.md)
- [leetcode 141 ](https://github.com/chefyuan/algorithm-base/blob/main/animation-simulation/%E9%93%BE%E8%A1%A8%E7%AF%87/leetcode141%E7%8E%AF%E5%BD%A2%E9%93%BE%E8%A1%A8.md)
- [leetcode 160 ](https://github.com/chefyuan/algorithm-base/blob/main/animation-simulation/%E9%93%BE%E8%A1%A8%E7%AF%87/leetcode%E7%9B%B8%E4%BA%A4%E9%93%BE%E8%A1%A8.md)
- [ offer 52 & leetcode 160 ](https://github.com/chefyuan/algorithm-base/blob/main/animation-simulation/%E9%93%BE%E8%A1%A8%E7%AF%87/%E5%89%91%E6%8C%87Offer52%E4%B8%A4%E4%B8%AA%E9%93%BE%E8%A1%A8%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AA%E5%85%AC%E5%85%B1%E8%8A%82%E7%82%B9.md)
- [leetcode 328 ](https://github.com/chefyuan/algorithm-base/blob/main/animation-simulation/%E9%93%BE%E8%A1%A8%E7%AF%87/leetcode328%E5%A5%87%E5%81%B6%E9%93%BE%E8%A1%A8.md)
### 🏳🌈

View File

@ -76,36 +76,4 @@ class Solution {
}
```
Go Code:
```go
func search(nums []int, target int) bool {
left := 0
right := len(nums) - 1
for (left <= right) {
mid := left+((right-left)>>1)
if (nums[mid] == target) {
return true
}
if (nums[mid] == nums[left]) {
left++
continue
}
if (nums[mid] > nums[left]) {
if (nums[mid] > target && target >= nums[left]) {
right = mid - 1
} else if (target > nums[mid] || target < nums[left]) {
left = mid + 1
}
}else if (nums[mid] < nums[left]) {
if (nums[mid] < target && target <= nums[right]) {
left = mid + 1
} else if (target < nums[mid] || target > nums[right]) {
right = mid - 1
}
}
}
return false
}
```

View File

@ -105,25 +105,3 @@ public:
};
```
Go Code:
```go
func findMin(nums []int) int {
left := 0
right := len(nums) - 1
for (left < right) {
if (nums[left] < nums[right]) {
return nums[left]
}
mid := left + ((right - left) >> 1)
if (nums[left] > nums[mid]) {
right = mid
} else {
left = mid + 1
}
}
return nums[left]
}
```

View File

@ -129,39 +129,3 @@ class Solution {
}
```
Go Code:
```go
func search(nums []int, target int) int {
// 左右指针
left := 0
right := len(nums) - 1
for (left <= right) {
mid := left + ((right - left) >> 1)
rightNum, leftNum, midNum := nums[right], nums[left], nums[mid]
if midNum == target {
return mid
}
//落在同一数组的情况同时落在数组1 或 数组2
if midNum >= leftNum {
//target 落在 left 和 mid 之间则移动我们的right完全有序的一个区间内查找
if midNum > target && target >= leftNum {
right = mid - 1
} else {
// target落在另一个无序区间 但和原数组的性质相符, 所以可以继续循环
left = mid + 1
}
} else {
//target 落在 mid 和 right 之间则移动我们的left完全有序的一个区间内查找
if midNum < target && target <= rightNum {
left = mid + 1
} else {
// target落在另一个无序区间 但和原数组的性质相符, 所以可以继续循环
right = mid - 1
}
}
}
return -1
}
```

View File

@ -169,48 +169,3 @@ class Solution {
}
```
Go Code:
```go
func searchRange(nums []int, target int) []int {
upper := upperBound(nums, target)
low := lowerBound(nums, target)
// 不存在情况
if (upper < low) {
return []int{-1, -1}
}
return []int{low, upper}
}
//计算下边界
func lowerBound(nums []int, target int) int {
left, right := 0, len(nums) - 1
for (left <= right) {
//这里需要注意计算mid
mid := left + ((right - left) >> 1)
if (target <= nums[mid]) {
//当目标值小于等于nums[mid]时,继续在左区间检索,找到第一个数
right = mid - 1
}else if (target > nums[mid]) {
//目标值大于nums[mid]时,则在右区间继续检索,找到第一个等于目标值的数
left = mid + 1
}
}
return left
}
//计算上边界
func upperBound(nums []int, target int) int {
left, right := 0, len(nums) - 1
for (left <= right) {
mid := left + ((right - left) >> 1)
if (target >= nums[mid]) {
left = mid + 1
}else if (target < nums[mid]) {
right = mid - 1
}
}
return right
}
```

View File

@ -1,4 +1,4 @@
> **[tan45du_one](https://raw.githubusercontent.com/tan45du/tan45du.github.io/master/个人微信.15egrcgqd94w.jpg)** ,备注 github + 题目 + 问题 向我反馈
> **[tan45du_one](https://raw.githubusercontent.com/tan45du/tan45du.github.io/master/个人微信.15egrcgqd94w.jpg)** ,备注 github + 题目 + 问题 向我反馈
>
>
>
@ -70,23 +70,3 @@ class Solution {
Go Code:
```go
func searchInsert(nums []int, target int) int {
left, right := 0, len(nums) - 1
for (left <= right) {
mid := left + ((right - left) >> 1)
// 查询成功
if nums[mid] == target {
return mid
// 右区间
} else if nums[mid] < target {
left = mid + 1
// 左区间
} else {
right = mid - 1
}
}
return left
}
```

View File

@ -86,32 +86,3 @@ class Solution {
}
```
Go Code:
```go
func searchMatrix(matrix [][]int, target int) bool {
if len(matrix) == 0 {
return false
}
// 行数
row := len(matrix)
//列数
col := len(matrix[0])
// 行数 * 列数 - 1 为右指针
left, right := 0, row * col - 1
for (left <= right) {
mid := left + ((right - left) >> 1)
//将一维坐标变为二维坐标
rownum := mid / col
colnum := mid % col
if matrix[rownum][colnum] == target {
return true
} else if matrix[rownum][colnum] > target {
right = mid - 1
} else if matrix[rownum][colnum] < target {
left = mid + 1
}
}
return false
}
```

View File

@ -78,4 +78,30 @@ class Solution {
}
```
Go Code:
```go
func inorderTraversal(root *TreeNode) []int {
res := []int{}
if root == nil {
return res
}
stk := []*TreeNode{}
cur := root
for len(stk) != 0 || cur != nil {
// 找到当前应该遍历的那个节点,并且把左子节点都入栈
for cur != nil {
stk = append(stk, cur)
cur = cur.Left
}
// 没有左子节点,则开始执行出栈操作
temp := stk[len(stk) - 1]
stk = stk[: len(stk) - 1]
res = append(res, temp.Val)
cur = temp.Right
}
return res
}
```
###

View File

@ -426,6 +426,34 @@ class Solution {
}
```
Go Code:
```go
func levelOrder(root *TreeNode) [][]int {
res := [][]int{}
if root == nil {
return res
}
// 初始化队列时记得把root节点加进去。
que := []*TreeNode{root}
for len(que) != 0 {
t := []int{}
// 这里一定要先求出来que的长度因为在迭代的过程中que的长度是变化的。
l := len(que)
for i := 0; i < l; i++ {
temp := que[0]
que = que[1:]
// 子节点不为空,就入队
if temp.Left != nil { que = append(que, temp.Left) }
if temp.Right != nil { que = append(que, temp.Right) }
t = append(t, temp.Val)
}
res = append(res, t)
}
return res
}
```
On On

View File

@ -95,3 +95,27 @@ class Solution {
}
}
```
Go Code:
```go
func preorderTraversal(root *TreeNode) []int {
res := []int{}
if root == nil {
return res
}
stk := []*TreeNode{root}
for len(stk) != 0 {
temp := stk[len(stk) - 1]
stk = stk[: len(stk) - 1]
if temp.Right != nil {
stk = append(stk, temp.Right)
}
if temp.Left != nil {
stk = append(stk, temp.Left)
}
res = append(res, temp.Val)
}
return res
}
```

View File

@ -104,6 +104,36 @@ class Solution {
}
```
Go Code:
```go
func postorderTraversal(root *TreeNode) []int {
res := []int{}
if root == nil {
return res
}
stk := []*TreeNode{}
cur := root
var pre *TreeNode
for len(stk) != 0 || cur != nil {
for cur != nil {
stk = append(stk, cur)
cur = cur.Left
}
// 这里符合本文最后的说法,使用先获取栈顶元素但是不弹出,根据栈顶元素的情况进行响应的处理。
temp := stk[len(stk) - 1]
if temp.Right == nil || temp.Right == pre {
stk = stk[: len(stk) - 1]
res = append(res, temp.Val)
pre = temp
} else {
cur = temp.Right
}
}
return res
}
```
`cur = stack.pop()` `cur = stack.peek()`便
On, On

View File

@ -100,3 +100,35 @@ public:
}
};
```
Go Code:
```go
func checkSubarraySum(nums []int, k int) bool {
m := map[int]int{}
// 由于前缀和%k可能为0所以需要给出没有元素的时候索引位置即-1
m[0] = -1
sum := 0
for i, num := range nums {
sum += num
key := sum % k
/*
// 题目中告诉k >= 1
key := sum
if k != 0 {
key = sum % k
}
*/
if v, ok := m[key]; ok {
if i - v >= 2 {
return true
}
// 避免更新最小索引
continue
}
// 保存的是最小的索引
m[key] = i
}
return false
}
```

View File

@ -182,3 +182,24 @@ public:
}
};
```
Go Code:
```GO
func subarraySum(nums []int, k int) int {
m := map[int]int{}
// m存的是前缀和没有元素的时候和为0且有1个子数组(空数组)满足条件即m[0] = 1
m[0] = 1
sum := 0
cnt := 0
for _, num := range nums {
sum += num
if v, ok := m[sum - k]; ok {
cnt += v
}
// 更新满足前缀和的子数组数量
m[sum]++
}
return cnt
}
```

View File

@ -107,3 +107,23 @@ public:
}
};
```
Go Code:
```go
func pivotIndex(nums []int) int {
presum := 0
for _, num := range nums {
presum += num
}
var leftsum int
for i, num := range nums {
// 比较左半和右半是否相同
if presum - leftsum - num == leftsum {
return i
}
leftsum += num
}
return -1
}
```

View File

@ -129,3 +129,21 @@ public:
}
};
```
Go Code:
```go
func subarraysDivByK(nums []int, k int) int {
m := make(map[int]int)
cnt := 0
sum := 0
m[0] = 1
for _, num := range nums {
sum += num
key := (sum % k + k) % k
cnt += m[key]
m[key]++
}
return cnt
}
```

View File

@ -58,3 +58,26 @@ class Solution {
}
}
```
GO Code:
```go
func dailyTemperatures(temperatures []int) []int {
l := len(temperatures)
if l == 0 {
return temperatures
}
stack := []int{}
arr := make([]int, l)
for i := 0; i < l; i++ {
for len(stack) != 0 && temperatures[i] > temperatures[stack[len(stack) - 1]] {
idx := stack[len(stack) - 1]
arr[idx] = i - idx
stack = stack[: len(stack) - 1]
}
// 栈保存的是索引
stack = append(stack, i)
}
return arr
}
```

View File

@ -89,4 +89,56 @@ class MaxQueue {
}
```
GO Code:
```go
type MaxQueue struct {
que []int // 普通队列
deq []int // 双端队列
size int // que的队列长度
}
func Constructor() MaxQueue {
return MaxQueue{
que: []int{},
deq: []int{},
}
}
// Is_empty 表示队列是否为空
func (mq *MaxQueue) Is_empty() bool {
return mq.size == 0
}
// Max_value 取最大值值,返回我们双端队列的对头即可,因为我们双端队列是单调递减的嘛
func (mq *MaxQueue) Max_value() int {
if mq.Is_empty() { return -1 }
return mq.deq[0]
}
// Push_back 入队
func (mq *MaxQueue) Push_back(value int) {
mq.que = append(mq.que, value)
// 维护单调递减队列
for len(mq.deq) != 0 && mq.deq[len(mq.deq) - 1] < value {
mq.deq = mq.deq[:len(mq.deq) - 1]
}
mq.deq = append(mq.deq, value)
mq.size++
}
// Pop_front 弹出队列头元素,并且返回其值。
func (mq *MaxQueue) Pop_front() int {
if mq.Is_empty() { return -1 }
ans := mq.que[0]
mq.que = mq.que[1:]
if mq.deq[0] == ans {
mq.deq = mq.deq[1:]
}
mq.size--
return ans
}
```
###

View File

@ -117,4 +117,35 @@ class Solution {
}
```
GO Code:
```go
func trap(height []int) int {
stack := []int{}
water := 0
// 最左边部分不会接雨水左边持续升高时stack都会弹出所有元素。
for i := 0; i< len(height); i++ {
for len(stack) != 0 && height[i] > height[stack[len(stack) - 1]] {
popnum := stack[len(stack) - 1]
// 出现相同高度的情况其实也可以不用处理如果不处理相同高度时后面的hig为0会产生很多无效的计算
for len(stack) != 0 && height[popnum] == height[stack[len(stack) - 1]] {
stack = stack[:len(stack) - 1]
}
if len(stack) == 0 { break }
le, ri := stack[len(stack) - 1], i
hig := min(height[ri], height[le]) - height[popnum]
wid := ri - le - 1
water += wid * hig
}
stack = append(stack, i)
}
return water
}
func min(a, b int) int {
if a < b { return a }
return b
}
```
###

View File

@ -73,4 +73,48 @@ class MinStack {
}
```
GO Code:
```go
type MinStack struct {
stack []int
minStk []int
}
/** initialize your data structure here. */
func Constructor() MinStack {
return MinStack{
stack: []int{},
minStk: []int{},
}
}
// Push 入栈,如果插入值,当前插入值小于栈顶元素,则入栈,栈顶元素保存的则为当前栈的最小元素
func (m *MinStack) Push(x int) {
m.stack = append(m.stack, x)
if len(m.minStk) == 0 || m.minStk[len(m.minStk) - 1] >= x {
m.minStk = append(m.minStk, x)
}
}
// Pop 出栈如果stack出栈等于minStk栈顶元素则说明此时栈内的最小元素改变了。
func (m *MinStack) Pop() {
temp := m.stack[len(m.stack) - 1]
m.stack = m.stack[: len(m.stack) - 1]
if temp == m.minStk[len(m.minStk) - 1] {
m.minStk = m.minStk[: len(m.minStk) - 1]
}
}
// Top stack的栈顶元素
func (m *MinStack) Top() int {
return m.stack[len(m.stack) - 1]
}
// GetMin minStk的栈顶元素
func (m *MinStack) GetMin() int {
return m.minStk[len(m.minStk) - 1]
}
```
###

View File

@ -72,3 +72,37 @@ class Solution {
}
}
```
GO Code:
```go
func maxSlidingWindow(nums []int, k int) []int {
l := len(nums)
if l == 0 {
return nums
}
arr := []int{}
// 维护一个单调递减的双向队列
deque := []int{}
for i := 0; i < k; i++ {
for len(deque) != 0 && deque[len(deque) - 1] < nums[i] {
deque = deque[:len(deque) - 1]
}
deque = append(deque, nums[i])
}
arr = append(arr, deque[0])
for i := k; i < l; i++ {
if nums[i - k] == deque[0] {
deque = deque[1:]
}
for len(deque) != 0 && deque[len(deque) - 1] < nums[i] {
deque = deque[:len(deque) - 1]
}
deque = append(deque, nums[i])
arr = append(arr, deque[0])
}
return arr
}
```

View File

@ -260,3 +260,46 @@ class Solution {
}
}
```
Go Code:
```go
func longestSubarray(nums []int, limit int) int {
maxdeq := []int{} // 递减队列
mindeq := []int{} // 递增队列
length := len(nums)
left, right, maxwin := 0, 0, 0
for right < length {
for len(maxdeq) != 0 && maxdeq[len(maxdeq) - 1] < nums[right] {
maxdeq = maxdeq[: len(maxdeq) - 1]
}
maxdeq = append(maxdeq, nums[right])
for len(mindeq) != 0 && mindeq[len(mindeq) - 1] > nums[right] {
mindeq = mindeq[: len(mindeq) - 1]
}
mindeq = append(mindeq, nums[right])
for maxdeq[0] - mindeq[0] > limit {
if maxdeq[0] == nums[left] {
maxdeq = maxdeq[1:]
}
if mindeq[0] == nums[left] {
mindeq = mindeq[1:]
}
left++
}
maxwin = max(maxwin, right - left + 1)
right++
}
return maxwin
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
```

View File

@ -202,3 +202,18 @@ class Solution {
}
}
```
Go Code:
```go
func twoSum(nums []int, target int) []int {
m := make(map[int]int)
for i, num := range nums {
if v, ok := m[target - num]; ok {
return []int{v, i}
}
m[num] = i
}
return []int{}
}
```

View File

@ -222,3 +222,24 @@ class Solution {
}
}
```
Go Code:
```go
func containsNearbyDuplicate(nums []int, k int) bool {
length := len(nums)
if length == 0 {
return false
}
m := map[int]int{}
for i := 0; i < length; i++ {
if v, ok := m[nums[i]]; ok {
if i - v <= k {
return true
}
}
m[nums[i]] = i
}
return false
}
```

View File

@ -182,3 +182,23 @@ class Solution {
}
}
```
Go Code:
```go
func removeElement(nums []int, val int) int {
length := len(nums)
if length == 0 {
return 0
}
i := 0
for j := 0; j < length; j++ {
if nums[j] == val {
continue
}
nums[i] = nums[j]
i++
}
return i
}
```

View File

@ -273,3 +273,26 @@ public:
}
};
```
Go Code:
```go
func firstMissingPositive(nums []int) int {
length := len(nums)
if length == 0 { return 1 }
for i := 0; i < length; i++ {
// 将不在正确位置的元素放在正确的位置上。
for nums[i] > 0 && nums[i] < length + 1 && nums[i] != i + 1 && nums[i] != nums[nums[i] - 1] {
j := nums[i] - 1
nums[i], nums[j] = nums[j], nums[i]
}
}
// 第一个不在正确位置上的元素就是结果。
for i := 0; i < length; i++ {
if nums[i] != i + 1 {
return i + 1
}
}
return length + 1
}
```

View File

@ -207,3 +207,27 @@ public:
}
};
```
Go Code:
```go
func findMaxConsecutiveOnes(nums []int) int {
cnt, maxCnt := 0, 0
for i := 0; i < len(nums); i++ {
if nums[i] == 1 {
cnt++
} else {
maxCnt = max(maxCnt, cnt)
cnt = 0
}
}
return max(maxCnt, cnt)
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
```

View File

@ -180,3 +180,40 @@ class Solution {
}
}
```
Go Code:
```go
func spiralOrder(matrix [][]int) []int {
res := []int{}
left, right := 0, len(matrix[0]) - 1
top, down := 0, len(matrix) - 1
for {
for i := left; i <= right; i++ {
res = append(res, matrix[top][i])
}
top++
if top > down { break }
for i := top; i <= down; i++ {
res = append(res, matrix[i][right])
}
right--
if left > right { break }
for i := right; i >= left; i-- {
res = append(res, matrix[down][i])
}
down--
if top > down { break }
for i := down; i >= top; i-- {
res = append(res, matrix[i][left])
}
left++
if left > right { break }
}
return res
}
```

View File

@ -217,3 +217,22 @@ public:
}
};
```
Go Code:
```go
func subarraySum(nums []int, k int) int {
m := map[int]int{}
m[0] = 1
sum := 0
cnt := 0
for _, num := range nums {
sum += num
if v, ok := m[sum - k]; ok {
cnt += v
}
m[sum]++
}
return cnt
}
```

View File

@ -360,3 +360,47 @@ class Solution {
}
}
```
Go Code:
```go
func generateMatrix(n int) [][]int {
res := make([][]int, n)
for i := 0; i < n; i++ {
res[i] = make([]int, n)
}
left, right := 0, n - 1
top, buttom := 0, n - 1
size, num := n * n, 1
for {
for i := left; i <= right; i++ {
res[top][i] = num
num++
}
top++
if num > size { break }
for i := top; i <= buttom; i++ {
res[i][right] = num
num++
}
right--
if num > size { break }
for i := right; i >= left; i-- {
res[buttom][i] = num
num++
}
buttom--
if num > size { break }
for i := buttom; i >= top; i-- {
res[i][left] = num
num++
}
left++
if num > size { break }
}
return res
}
```

View File

@ -122,3 +122,19 @@ class Solution {
}
}
```
Go Code:
```go
func plusOne(digits []int) []int {
l := len(digits)
for i := l - 1; i >= 0; i-- {
digits[i] = (digits[i] + 1) % 10
if digits[i] != 0 {
return digits
}
}
digits = append([]int{1}, digits...)
return digits
}
```

View File

@ -149,6 +149,30 @@ class Solution {
}
```
Go Code:
```go
func sortColors(nums []int) {
length := len(nums)
left, right := 0, length - 1
i := left
for i <= right {
if nums[i] == 2 {
// 把2换到最后
nums[i], nums[right] = nums[right], nums[i]
right--
} else if nums[i] == 0 {
// 把0换到最前面
nums[i], nums[left] = nums[left], nums[i]
i++
left++
} else {
i++
}
}
}
```
使
[0,0,0,1,1,1,2,2,2]
@ -286,3 +310,27 @@ class Solution {
}
}
```
Go Code:
```go
func sortColors(nums []int) {
length := len(nums)
left, right := 0, length - 1
for i := 0; i <= right; i++ {
if nums[i] == 0 {
// 为0时和头交换
nums[i], nums[left] = nums[left], nums[i]
left++
} else if nums[i] == 2 {
// 为2时和尾交换
nums[i], nums[right] = nums[right], nums[i]
right--
// 不为1时需要把i减回去
if nums[i] != 1 {
i--
}
}
}
}
```

View File

@ -174,3 +174,24 @@ class Solution {
}
}
```
Go Code:
```go
func findRepeatNumber(nums []int) int {
l := len(nums)
if l == 0 {
return -1
}
for i := 0; i < l; i++ {
// 将nums[i]换到i的位置。
for nums[i] != i {
if nums[i] == nums[nums[i]] {
return nums[i]
}
nums[i], nums[nums[i]] = nums[nums[i]], nums[i]
}
}
return -1
}
```

View File

@ -119,3 +119,33 @@ class Solution {
}
}
```
Go Code:
```go
func minSubArrayLen(target int, nums []int) int {
length := len(nums)
winLen := length + 1
i := 0
sum := 0
for j := 0; j < length; j++ {
sum += nums[j]
for sum >= target {
winLen = min(winLen, j - i + 1)
sum -= nums[i]
i++
}
}
if winLen == length + 1 {
return 0
}
return winLen
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
```

View File

@ -162,3 +162,50 @@ class Solution {
}
}
```
Go Code:
```go
func threeSum(nums []int) [][]int {
res := [][]int{}
length := len(nums)
if length < 3 {
return res
}
sort.Ints(nums)
for i := 0; i < length - 2; i++ {
// 去重
if i != 0 && nums[i] == nums[i - 1] {
continue
}
l, r := i + 1, length - 1
for l < r {
/*
// 下面两个for循环的去重也可以用下面的代码替换
if l != i + 1 && nums[l] == nums[l - 1] {
l++
continue
}
*/
if nums[i] + nums[l] + nums[r] == 0 {
res = append(res, []int{nums[i], nums[l], nums[r]})
for l < r && nums[l] == nums[l + 1] {
l++
}
for l < r && nums[r] == nums[r - 1] {
r--
}
l++
r--
} else if nums[i] + nums[l] + nums[r] < 0 {
l++
} else {
r--
}
}
}
return res
}
```

View File

@ -54,6 +54,21 @@ class Solution {
}
```
Go Code:
```go
func twoSum(nums []int, target int) []int {
m := make(map[int]int)
for i, num := range nums {
if v, ok := m[target - num]; ok {
return []int{v, i}
}
m[num] = i
}
return []int{}
}
```
###
####

View File

@ -95,3 +95,57 @@ class Solution {
}
}
```
Go Code:
```go
func fourSum(nums []int, target int) [][]int {
res := [][]int{}
length := len(nums)
if length < 4 {
return res
}
sort.Ints(nums)
for i := 0; i < length - 3; i++ {
// 去重
if i != 0 && nums[i] == nums[i - 1] {
continue
}
for j := i + 1; j < length - 2; j++ {
// 去重
if j != i + 1 && nums[j] == nums[j - 1] {
continue
}
l, r := j + 1, length - 1
for l < r {
/*
// 下面两个for循环的去重也可以用下面的代码替换
if l != i + 1 && nums[l] == nums[l - 1] {
l++
continue
}
*/
sum := nums[i] + nums[j] + nums[l] + nums[r]
if sum == target {
res = append(res, []int{nums[i], nums[j], nums[l], nums[r]})
for l < r && nums[l] == nums[l + 1] {
l++
}
for l < r && nums[r] == nums[r - 1] {
r--
}
l++
r--
} else if sum < target {
l++
} else {
r--
}
}
}
}
return res
}
```

View File

@ -131,6 +131,26 @@ class Solution:
return y
```
Go Code:
```go
func singleNumber(nums []int) int {
if len(nums) == 1 {
return nums[0]
}
m := map[int]int{}
for _, x := range nums {
m[x]++
}
for k, v := range m {
if v == 1 {
return k
}
}
return 0
}
```
###
####
@ -208,6 +228,25 @@ class Solution:
return nums[len(nums) - 1]
```
Go Code:
```go
func singleNumber(nums []int) int {
if len(nums) == 1 {
return nums[0]
}
sort.Ints(nums)
for i := 1; i < len(nums) - 1; i+=2 {
if nums[i] == nums[i - 1] {
continue
} else {
return nums[i - 1]
}
}
return nums[len(nums) - 1]
}
```
### HashSet
####
@ -565,4 +604,17 @@ class Solution:
return reduce(lambda num, x: num ^ x, nums, 0)
```
Go Code:
```go
func singleNumber(nums []int) int {
res := 0
for _, x := range nums {
res ^= x
}
return res
}
```
6

View File

@ -216,6 +216,27 @@ class Solution:
return res
```
Go Code:
```go
func singleNumber(nums []int) int {
res := 0
// Go语言中int占32位以上
for i := 0; i < 64; i++ {
cnt := 0
for j := 0; j < len(nums); j++ {
if (nums[j] >> i & 1) == 1 {
cnt++
}
}
if cnt % 3 != 0{
res = res | 1 << i
}
}
return res
}
```
> **<<** **<<** 0

View File

@ -263,3 +263,26 @@ class Solution:
arr[1] ^= y
return arr
```
Go Code:
```go
func singleNumber(nums []int) []int {
temp := 0
for _, x := range nums {
temp ^= x
}
// 保留最后那个1为了区分两个数
group := temp & (^temp + 1)
res := make([]int, 2)
for _, x := range nums {
if group & x == 0{
res[0] ^= x
} else {
res[1] ^= x
}
}
return res
}
```

View File

@ -173,6 +173,30 @@ class Solution {
}
```
Go Code:
```go
func isPalindrome(head *ListNode) bool {
// 将节点中的值按顺序放在arr中。
arr := []int{}
node := head
for node != nil {
arr = append(arr, node.Val)
node = node.Next
}
// 双指针判断是否为回文
l, r := 0, len(arr) - 1
for l < r {
if arr[l] != arr[r] {
return false
}
l++
r--
}
return true
}
```
****
@ -457,3 +481,52 @@ class Solution {
}
}
```
Go Code:
```go
func isPalindrome(head *ListNode) bool {
if head == nil || head.Next == nil {
return true
}
midNode := searchMidNode(head)
backHalf := reverse(midNode.Next)
// 判断左右两边是否一样(回文)
p1, p2 := head, backHalf
for p2 != nil {
if p1.Val != p2.Val {
midNode.Next = reverse(backHalf)
return false
}
p1 = p1.Next
p2 = p2.Next
}
// 不破坏原来的数据
midNode.Next = reverse(backHalf)
return true
}
// searchMidNode 求中间的节点
func searchMidNode(head *ListNode) *ListNode {
fast, slow := head, head
for fast.Next != nil && fast.Next.Next != nil {
fast = fast.Next.Next
slow = slow.Next
}
return slow
}
// reverse 反转链表
func reverse(node *ListNode) *ListNode {
var pre *ListNode
for node != nil {
nxt := node.Next
node.Next = pre
pre = node
node = nxt
}
return pre
}
```

View File

@ -124,3 +124,20 @@ class Solution {
}
}
```
Go Code:
```go
func hasCycle(head *ListNode) bool {
if head == nil { return false }
s, f := head, head
for f != nil && f.Next != nil {
s = s.Next
f = f.Next.Next
if s == f {
return true
}
}
return false
}
```

View File

@ -297,3 +297,27 @@ class Solution {
}
}
```
Go Code:
```go
func detectCycle(head *ListNode) *ListNode {
if head == nil { return nil }
s, f := head, head
for f != nil && f.Next != nil {
s = s.Next
f = f.Next.Next
// 快慢指针相遇
if f == s {
// 快指针从头开始一步一步走,也可以用一个新的指针
f = head
for f != s {
f = f.Next
s = s.Next
}
return f
}
}
return nil
}
```

View File

@ -257,3 +257,34 @@ class Solution {
}
}
```
Go Code:
```go
func insertionSortList(head *ListNode) *ListNode {
if head == nil || head.Next == nil { return head }
root := &ListNode{
Next: head,
}
cur, nxt := head, head.Next
for nxt != nil {
// 有序的不需要换位置
if cur.Val <= nxt.Val {
cur = cur.Next
nxt = nxt.Next
continue
}
temp := root
for temp.Next.Val <= nxt.Val {
temp = temp.Next
}
// 此时找到合适的位置
cur.Next = nxt.Next
nxt.Next = temp.Next
temp.Next = nxt
// 继续向下
nxt = cur.Next
}
return root.Next
}
```

View File

@ -164,6 +164,27 @@ class Solution {
}
```
Go Code:
```go
func reverseList(head *ListNode) *ListNode {
if head == nil || head.Next == nil { return head }
cur := head
var pre *ListNode
for cur != nil {
nxt := cur.Next
cur.Next = pre
pre = cur
cur = nxt
if nxt == nil {
return pre
}
nxt = nxt.Next
}
return pre
}
```
****

View File

@ -155,3 +155,23 @@ class Solution {
}
}
```
Go Code:
```go
func oddEvenList(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
}
odd, even := head, head.Next
evenHead := even
for odd.Next != nil && even.Next != nil {
odd.Next = even.Next
odd = odd.Next
even.Next = odd.Next
even = even.Next
}
odd.Next = evenHead
return head
}
```

View File

@ -194,3 +194,30 @@ class Solution {
}
}
```
Go Code:
```go
func deleteDuplicates(head *ListNode) *ListNode {
// 新建一个头结点,他的下一个节点才是开始
root := &ListNode{
Next: head,
}
pre, cur := root, head
for cur != nil && cur.Next != nil {
if cur.Val == cur.Next.Val {
// 相等的话cur就一直向后移动
for cur != nil && cur.Next != nil && cur.Val == cur.Next.Val {
cur = cur.Next
}
// 循环后移动到了最后一个相同的节点。
cur = cur.Next
pre.Next = cur
} else {
cur = cur.Next
pre = pre.Next
}
}
return root.Next
}
```

View File

@ -187,3 +187,29 @@ class Solution {
}
}
```
Go Code:
```go
func partition(head *ListNode, x int) *ListNode {
big, small := &ListNode{}, &ListNode{}
headBig, headSmall := big, small
temp := head
for temp != nil {
// 分开存
if temp.Val < x {
small.Next = temp
small = small.Next
} else {
big.Next = temp
big = big.Next
}
temp = temp.Next
}
// 最后一个节点指向nil
big.Next = nil
// 存小数的链表和存大数的连起来
small.Next = headBig.Next
return headSmall.Next
}
```

View File

@ -263,3 +263,46 @@ class Solution {
}
}
```
GoCode:
```go
func reverseBetween(head *ListNode, left int, right int) *ListNode {
root := &ListNode{
Next: head,
}
temp := root
i := 0
// left的前一个节点
for ; i < left - 1; i++ {
temp = temp.Next
}
leftNode := temp
// right的后一个节点
for ; i < right; i++ {
temp = temp.Next
}
rightNode := temp.Next
// 切断链表
temp.Next = nil
newhead := leftNode.Next
leftNode.Next = nil
// 反转后将3段链表接上。
leftNode.Next = reverse(newhead)
newhead.Next = rightNode
return root.Next
}
func reverse(head *ListNode) *ListNode {
var pre *ListNode
cur := head
for cur != nil {
temp := cur
cur = cur.Next
temp.Next = pre
pre = temp
}
return pre
}
```

View File

@ -146,3 +146,29 @@ class Solution {
}
}
```
Go Code:
```go
func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode {
root := &ListNode{}
node := root
for l1 != nil && l2 != nil {
if l1.Val < l2.Val {
node.Next = l1
l1 = l1.Next
} else {
node.Next = l2
l2 = l2.Next
}
node = node.Next
}
// node接上l1或l2剩下的节点
if l1 != nil {
node.Next = l1
} else {
node.Next = l2
}
return root.Next
}
```

View File

@ -265,6 +265,28 @@ class Solution {
}
```
Go Code:
```go
func getIntersectionNode(headA, headB *ListNode) *ListNode {
tempA, tempB := headA, headB
for tempA != tempB {
// 如果不为空就指针下移,为空就跳到另一链表的头部
if tempA == nil {
tempA = headB
} else {
tempA = tempA.Next
}
if tempB == nil {
tempB = headA
} else {
tempB = tempB.Next
}
}
return tempA
}
```
<br/>

View File

@ -163,3 +163,21 @@ class Solution {
}
}
```
Go Code:
```go
func getKthFromEnd(head *ListNode, k int) *ListNode {
if head == nil { return head }
pro, after := head, head
//先移动绿指针到指定位置
for i := 0; i < k - 1; i++ {
pro = pro.Next
}
for pro.Next != nil {
pro = pro.Next
after = after.Next
}
return after
}
```

View File

@ -135,3 +135,17 @@ class Solution {
}
}
```
Go Code:
```go
func middleNode(head *ListNode) *ListNode {
// 快慢指针
fast, slow := head, head
for fast != nil && fast.Next != nil {
fast = fast.Next.Next
slow = slow.Next
}
return slow
}
```

View File

@ -267,3 +267,40 @@ class Solution {
}
}
```
Go Code:
```go
func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
root := &ListNode{}
temp := root
// 用来保存进位值初始化为0
mod := 0
for (l1 != nil || l2 != nil) {
l1num := 0
if l1 != nil { l1num = l1.Val }
l2num := 0
if l2 != nil { l2num = l2.Val }
// 将链表的值和进位值相加,得到为返回链表的值
sum := l1num + l2num + mod
// 更新进位值例18/10=19/10=0
mod = sum / 10
// 新节点保存的值18%8=2则添加2
sum = sum % 10
newNode := &ListNode{
Val: sum,
}
temp.Next = newNode
temp = temp.Next
if l1 != nil { l1 = l1.Next }
if l2 != nil { l2 = l2.Next }
}
if mod != 0 {
newNode := &ListNode{
Val: mod,
}
temp.Next = newNode
}
return root.Next
}
```