1.两数之和
func twoSum(nums []int, target int) []int {
m := make(map[int]int)
for i:=0; i<len(nums); i++ {
t := target - nums[i]
if _, ok := m[t]; ok {
return []int{i, m[t]}
}
m[nums[i]] = i
}
return nil
}
11.盛最多水的容器
双指针,从宽度最长开始,每次向内缩小时缩小的长度固定,所以肯定要缩小高度小的那个柱子
func maxArea(height []int) int {
res := 0
l := 0
r := len(height) - 1
for l < r {
curWidth := getmin(height[l], height[r])
curArea := curWidth * (r-l)
if curArea > res{
res = curArea
}
if height[l] < height[r]{
l ++
}else{
r --
}
}
return res
}
func getmin(a int, b int) int{
if a < b{
return a
}else{
return b
}
}
26.删除有序数组中的重复项
遍历一次即可,因为是不严格递增有重复数组,所以可以把后面的某个数组直接覆盖前面已经扫描过的位置的值
func removeDuplicates(nums []int) int {
pos := 0
left, right := 0, 0
for right < len(nums){
nums[pos] = nums[right]
pos += 1
for right < len(nums) && nums[left] == nums[right]{
right ++
}
left = right
}
return pos
}
27.移除元素
func removeElement(nums []int, val int) int {
pos := 0
for i:=0; i<len(nums); i++{
if nums[i]!=val{
nums[pos] = nums[i]
pos ++
}
}
return pos
}
35.搜索插入位置
使用左闭右闭区间,for left <= right,最后返回right+1,这个题是无重复元素的排序数组
func searchInsert(nums []int, target int) int {
left, right := 0, len(nums)-1
for left <= right{
mid := (left + right) / 2
if (target < nums[mid]){
right = mid - 1
}else if (target > nums[mid]){
left = mid +1
}else {
return mid
}
}
return right + 1
}
28.找出字符串中第一个匹配项的下标
func strStr(haystack string, needle string) int {
if len(needle) ==0{
return 0
}
for i:=0; i<len(haystack)-len(needle)+1; i++{
j := 0
for ; j<len(needle); j++{
if haystack[i+j]!=needle[j]{
break
}
}
if j==len(needle){
return i
}
}
return -1
}
78.子集
func subsets(nums []int) [][]int {
result := make([][]int, 0)
curlist := make([]int, 0)
dfs(nums, 0, curlist, &result)
return result
}
func dfs(nums []int, pos int, curlist []int, result *[][]int){
if pos == len(nums){
*result = append(*result, append([]int(nil), curlist...))
return
}
curlist = append(curlist, nums[pos])
dfs(nums, pos+1, curlist, result)
curlist = curlist[:len(curlist)-1]
dfs(nums, pos+1, curlist, result)
}
155.最小栈
题目:设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。
思路:用两个栈实现,一个最小栈始终保证最小值在顶部,两个栈大小永远一样
type MinStack struct {
min []int
stack []int
}
func Constructor() MinStack {
return MinStack{
min: make([]int, 0),
stack: make([]int, 0),
}
}
func (this *MinStack) Push(val int) {
this.stack = append(this.stack, val)
curMin := this.GetMin()
if curMin < val {
this.min = append(this.min, curMin)
}else{
this.min = append(this.min, val)
}
}
func (this *MinStack) Pop() {
if len(this.stack) == 0{
return
}else{
this.stack = this.stack[:len(this.stack)-1]
this.min = this.min[:len(this.min)-1]
}
}
func (this *MinStack) Top() int {
if len(this.stack) == 0{
return 0
}else{
return this.stack[len(this.stack)-1]
}
}
func (this *MinStack) GetMin() int {
if len(this.min) == 0{
return 1<<31
}else{
return this.min[len(this.min)-1]
}
}
/**
* Your MinStack object will be instantiated and called as such:
* obj := Constructor();
* obj.Push(val);
* obj.Pop();
* param_3 := obj.Top();
* param_4 := obj.GetMin();
*/
150.逆波兰表达式求值
题目描述:
给你一个字符串数组
tokens,表示一个根据逆波兰表示法表示的算术表达式。请你计算该表达式。返回一个表示表达式值的整数。
思路:思路:通过栈保存原来的元素,遇到表达式弹出运算,再推入结果,重复这个过程
func evalRPN(tokens []string) int {
if len(tokens) == 0{
return 0
}
stack := make([]int, 0)
for i:=0; i<len(tokens); i++{
switch tokens[i]{
case "+", "-", "*", "/":
if len(tokens) < 2{
return -1
}
b := stack[len(stack)-1]
a := stack[len(stack)-2]
stack = stack[:len(stack)-2]
var result int
switch tokens[i]{
case "+":
result = a + b
case "-":
result = a - b
case "*":
result = a * b
case "/":
result = a / b
}
stack = append(stack, result)
default:
val, _ := strconv.Atoi(tokens[i])
stack = append(stack, val)
}
}
return stack[0]
}
94.二叉树的中序遍历
栈方式模拟二叉树中序遍历
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func inorderTraversal(root *TreeNode) []int {
result := make([]int, 0)
if root == nil {
return result
}
stack := make([]*TreeNode, 0)
for {
for root != nil{
stack = append(stack, root)
root = root.Left //左
}
//弹出,根
if len(stack) == 0 {
break
}
curNode := stack[len(stack)-1]
stack = stack[:len(stack)-1]
result = append(result, curNode.Val)
root = curNode.Right //又
}
return result
}
133.克隆图
题目描述:给你无向连通图中一个节点的引用,请你返回该图的深拷贝(克隆)
思路:递归遍历,将遍历到的节点存入一个map中
func cloneGraph(node *Node) *Node {
visited := map[*Node]*Node{}
return deepClone(node, visited)
}
func deepClone(node *Node, visited map[*Node]*Node) *Node{
if node == nil{
return nil
}
if v, ok := visited[node]; ok{
//已经访问过,直接返回
return v
}
newNode := &Node{
Val: node.Val,
Neighbors: make([]*Node, len(node.Neighbors)),
}
visited[node] = newNode
for i:= 0; i<len(node.Neighbors); i++{
newNode.Neighbors[i] = deepClone(node.Neighbors[i], visited)
}
return newNode
}
200.岛屿数量
func numIslands(grid [][]byte) int {
res := 0
for i:=0; i<len(grid); i++{
for j:=0; j<len(grid[i]); j++{
if grid[i][j] == '1'{
res++
dfs(grid, i, j)
}
}
}
return res
}
var next [][]int = [][]int{{1,0}, {0,1}, {-1,0}, {0,-1}}
func dfs(grid [][]byte, x int, y int){
if x<0 || x>=len(grid) || y<0 || y>=len(grid[x]){
return
}
if grid[x][y] == '0'{
return
}
grid[x][y] = '0'
for i:=0; i<4; i++{
tx := x + next[i][0]
ty := y + next[i][1]
dfs(grid, tx, ty)
}
}
095.最长公共子序列
https://leetcode.cn/problems/qJnOS7/
func longestCommonSubsequence(text1 string, text2 string) int {
m, n := len(text1), len(text2)
dp := make([][]int, m+1)
for i:= range dp{
dp[i] = make([]int, n+1)
}
for i, c1 := range text1{
for j, c2 := range text2{
if c1 == c2{
dp[i+1][j+1] = dp[i][j]+1
}else{
dp[i+1][j+1] = getMax(dp[i][j+1], dp[i+1][j])
}
}
}
return dp[m][n]
}
func getMax(a, b int) int{
if a>b{
return a
}else{
return b
}
}
优化到一维
dp[i]标识text2到i下标时,匹配的最大长度
int longestCommonSubsequence(string text1, string text2) {
int len1 = text1.size(), len2 = text2.size();
vector<int> dp(len2 + 1);
for (int i = 1; i <= len1; i++) {
int pre = 0;
for (int j = 1; j <= len2; j++) {
int tmp = dp[j];
if (text1[i - 1] == text2[j - 1]) dp[j] = pre + 1;
else dp[j] = max(dp[j], dp[j - 1]);
pre = tmp;
}
}
return dp[len2];
}
141.环形链表
func hasCycle(head *ListNode) bool {
flag := map[*ListNode]struct{}{}
curNodePtr := head
for curNodePtr!=nil{
if _, ok := flag[curNodePtr]; ok{
return true
}
flag[curNodePtr] = struct{}{}
curNodePtr = curNodePtr.Next
}
return false
}
435.无重叠区间
func eraseOverlapIntervals(intervals [][]int) int {
n := len(intervals)
if n==0{
return 0
}
sort.Slice(intervals, func(i, j int)bool{
return intervals[i][1] < intervals[j][1]
})
ans := 0
curRight := intervals[0][1]
for i:=1; i<n; i++{
if intervals[i][0] < curRight{
ans++
}else{
curRight = intervals[i][1]
}
}
return ans
}
169.多数元素
func majorityElement(nums []int) int {
ans := nums[0]
ansCnt := 1
for i:=1; i<len(nums); i++{
if nums[i] ==ans{
ansCnt+=1
}else{
ansCnt -=1
if ansCnt==0{
ansCnt = 1
ans = nums[i]
}
}
}
return ans
}
105.从前序与中序遍历序列构造二叉树
func buildTree(preorder []int, inorder []int) *TreeNode {
if len(preorder)==0{
return nil
}
root := &TreeNode{Val: preorder[0], Left: nil, Right: nil}
i := 0
for ; i<len(inorder); i++{
if inorder[i] == preorder[0]{
break
}
}
root.Left = buildTree(preorder[1:len(inorder[:i])+1], inorder[:i])
root.Right = buildTree(preorder[len(inorder[:i])+1:], inorder[i+1:])
return root
}
106.从中序与后序遍历序列构造二叉树
func buildTree(inorder []int, postorder []int) *TreeNode {
if len(inorder)==0{
return nil
}
root := &TreeNode{Val: postorder[len(postorder)-1], Left: nil, Right: nil}
pos := 0
for ; pos< len(inorder); pos++{
if inorder[pos]==postorder[len(postorder)-1]{
break
}
}
root.Left = buildTree(inorder[:pos], postorder[:pos])
root.Right = buildTree(inorder[pos+1:], postorder[pos:len(postorder)-1])
return root
}
102.二叉树的层序遍历
func levelOrder(root *TreeNode) [][]int {
if root==nil{
return [][]int{}
}
ans := [][]int{}
nodeStack := make([]*TreeNode, 0)
nodeStack = append(nodeStack, root)
for len(nodeStack) != 0{
temp := []int{}
nodeCnt := len(nodeStack)
for i:=0; i<nodeCnt; i++{
curNode := nodeStack[0]
nodeStack = nodeStack[1:]
temp = append(temp, curNode.Val)
if curNode.Left != nil{
nodeStack = append(nodeStack, curNode.Left)
}
if curNode.Right != nil{
nodeStack = append(nodeStack, curNode.Right)
}
}
ans = append(ans, temp)
}
return ans
}
146.LRU缓存
type LRUCache struct {
curSize int
capacity int
head, tail *LinkNode
cache map[int]*LinkNode
}
type LinkNode struct{
key, val int
prev, next *LinkNode
}
func Constructor(capacity int) LRUCache {
lruCache := LRUCache{
curSize: 0,
capacity: capacity,
head: &LinkNode{},
tail: &LinkNode{},
cache: map[int]*LinkNode{},
}
lruCache.head.next = lruCache.tail
lruCache.tail.prev = lruCache.head
return lruCache
}
func (this *LRUCache) addToHead(node *LinkNode){
node.prev = this.head
node.next = this.head.next
this.head.next.prev = node
this.head.next = node
}
func (this *LRUCache) removeNode(node *LinkNode){
node.prev.next = node.next
node.next.prev = node.prev
}
func (this *LRUCache) moveToHead(node *LinkNode){
this.removeNode(node)
this.addToHead(node)
}
func (this *LRUCache) removeTail() *LinkNode{
node := this.tail.prev
this.removeNode(node)
return node
}
func (this *LRUCache) Get(key int) int {
if _, ok := this.cache[key]; !ok{
return -1
}
node := this.cache[key]
this.moveToHead(node)
return node.val
}
func (this *LRUCache) Put(key int, value int) {
if _, ok := this.cache[key]; ok{
node := this.cache[key]
node.val = value
this.moveToHead(node)
}else{
node := &LinkNode{
key: key,
val: value,
prev: nil,
next: nil,
}
if this.curSize < this.capacity{
this.addToHead(node)
this.curSize += 1
this.cache[key] = node
}else{
removedNode := this.removeTail()
delete(this.cache, removedNode.key)
this.addToHead(node)
this.cache[key] = node
}
}
}
/**
* Your LRUCache object will be instantiated and called as such:
* obj := Constructor(capacity);
* param_1 := obj.Get(key);
* obj.Put(key,value);
*/
49.字母异位词分组
func groupAnagrams(strs []string) [][]string {
mp := map[string][]string{}
for _, str := range strs{
s := []byte(str)
sort.Slice(s, func(i, j int)bool{return s[i]<s[j]})
sortedStr := string(s)
mp[sortedStr] = append(mp[sortedStr], str)
}
ans := make([][]string, 0)
for _, v := range mp{
ans = append(ans, v)
}
return ans
}
128.最长连续序列
func longestConsecutive(nums []int) int {
keyCount := map[int]int{}
numsLen := len(nums)
for i:=0; i<numsLen; i++{
keyCount[nums[i]]++
}
longestLen := 0
for num := range keyCount{
if keyCount[num-1]==0{
curNum := num
curLen := 1
for keyCount[curNum+1]!=0{
curNum++
curLen++
}
if curLen > longestLen{
longestLen = curLen
}
}
}
return longestLen
}
15.三数之和
func threeSum(nums []int) [][]int {
sort.Ints(nums)
numMap := map[int]int{}
numsLen := len(nums)
for i:=0; i<numsLen; i++{
numMap[nums[i]]++
}
type tuple struct{
x, y, z int
}
tupleMap := map[tuple]bool{}
for i:=0; i<numsLen-2; i++{
for j:=i+1; j<numsLen-1; j++{
thirdNum := 0-nums[i]-nums[j]
if thirdNum < nums[j]{
continue
}
if thirdNum == nums[j]{
if thirdNum == nums[i] {
if numMap[thirdNum]>=3{
curTuple := tuple{nums[i], nums[j], thirdNum}
tupleMap[curTuple] = true
}
}else if numMap[thirdNum]>=2{
curTuple := tuple{nums[i], nums[j], thirdNum}
tupleMap[curTuple] = true
}
}else if numMap[thirdNum] !=0 {
curTuple := tuple{nums[i], nums[j], thirdNum}
tupleMap[curTuple] = true
}
}
}
ans := [][]int{}
for t := range tupleMap{
curAnsNode := []int{}
curAnsNode = append(curAnsNode, t.x)
curAnsNode = append(curAnsNode, t.y)
curAnsNode = append(curAnsNode, t.z)
ans = append(ans, curAnsNode)
}
return ans
}
189.轮转数组
func rotate(nums []int, k int) {
newNums := make([]int, len(nums))
for i, v := range nums {
newNums[(i+k)%len(nums)] = v
}
copy(nums, newNums)
}
func rotate(nums []int, k int) {
k %= len(nums) // 轮转 k 次等于轮转 k%n 次
slices.Reverse(nums)
slices.Reverse(nums[:k])
slices.Reverse(nums[k:])
}
56. 合并区间
func merge(intervals [][]int) [][]int {
sort.Slice(intervals, func(i, j int) bool {
return intervals[i][0] < intervals[j][0]
})
ans := [][]int{}
start, end := intervals[0][0], intervals[0][1]
for i := 1; i < len(intervals); i++ {
if intervals[i][0] > end{
ans = append(ans, []int{start, end})
start = intervals[i][0]
end = intervals[i][1]
}else{
end = getMax(end, intervals[i][1])
}
}
ans = append(ans, []int{start, end})
return ans
}
func getMin(a, b int) int {
if a < b {
return a
}
return b
}
func getMax(a, b int) int{
if a < b{
return b
}
return a
}