Skip to content

Commit 6daea0d

Browse files
committed
add leetcode and algs
1 parent 76cb1bf commit 6daea0d

13 files changed

+408
-11
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package leetcode
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
)
7+
8+
type node struct {
9+
next map[uint8]*node
10+
isEnd bool
11+
}
12+
13+
func (n *node) String() string {
14+
return fmt.Sprintf("isEnd=%t, next=%v", n.isEnd, n.next)
15+
}
16+
17+
func addWord(n *node, word string) {
18+
for i := 0; i < len(word); i++ {
19+
if n.next[word[i]-'a'] == nil {
20+
n.next[word[i]-'a'] = &node{next: make(map[uint8]*node, 26)}
21+
}
22+
n = n.next[word[i]-'a']
23+
}
24+
n.isEnd = true
25+
}
26+
27+
// 思路1:使用Trie树,4ms,击败6.37%用户,性能损耗在需要先扫描全部字符串,然后再判断
28+
// 占用存储4.7MB,击败5.1%用户
29+
func longestCommonPrefix(strs []string) string {
30+
var root = &node{next: make(map[uint8]*node, 26)}
31+
32+
for _, s := range strs {
33+
if s == "" {
34+
return ""
35+
}
36+
addWord(root, s)
37+
}
38+
39+
fmt.Println(root)
40+
var ans bytes.Buffer
41+
for cur := root; cur != nil && len(cur.next) == 1 && cur.isEnd == false; {
42+
for k, n := range cur.next {
43+
ans.WriteByte(k + 'a')
44+
cur = n
45+
}
46+
}
47+
48+
return ans.String()
49+
}
50+
51+
// 直接横向扫描, 耗时0ms,击败100%, 存储2.4MB,击败98.56%
52+
func longestCommonPrefix1(strs []string) string {
53+
if len(strs) == 0 {
54+
return ""
55+
}
56+
if len(strs) == 1 {
57+
return strs[0]
58+
}
59+
60+
var ans = make([]byte, 0, 2)
61+
s1 := strs[0]
62+
var equal bool
63+
for i := 0; i < len(s1); i++ {
64+
equal = true
65+
for j := 1; j < len(strs); j++ {
66+
if len(strs[j]) <= i || strs[j][i] != s1[i] {
67+
equal = false
68+
}
69+
}
70+
if equal {
71+
ans = append(ans, s1[i])
72+
} else {
73+
break
74+
}
75+
}
76+
77+
return string(ans)
78+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package leetcode
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
)
7+
8+
func TestLongestCommonPrefix(t *testing.T) {
9+
strs := []string{"flowe", "flow", ""}
10+
//strs := []string{"dog", "racecar", "car"}
11+
ans := longestCommonPrefix1(strs)
12+
fmt.Println(ans)
13+
}

algs/leetcode/155_MinStack.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package leetcode
2+
3+
type MinStack struct {
4+
eles []int
5+
minNums []int
6+
}
7+
8+
// 思路:双栈,一个存储正常的值,一个存储最小值(有数据冗余)
9+
/** initialize your data structure here. */
10+
func Constructor() MinStack {
11+
return MinStack{
12+
eles: make([]int, 0),
13+
minNums: make([]int, 0),
14+
}
15+
}
16+
17+
func (this *MinStack) Push(x int) {
18+
this.eles = append(this.eles, x)
19+
20+
if len(this.minNums) == 0 {
21+
this.minNums = append(this.minNums, x)
22+
} else {
23+
if x > this.GetMin() {
24+
this.minNums = append(this.minNums, this.GetMin())
25+
} else {
26+
this.minNums = append(this.minNums, x)
27+
}
28+
}
29+
}
30+
31+
func (this *MinStack) Pop() {
32+
if len(this.eles) == 0 {
33+
return
34+
}
35+
36+
this.eles = this.eles[:len(this.eles)-1]
37+
this.minNums = this.minNums[:len(this.minNums)-1]
38+
}
39+
40+
func (this *MinStack) Top() int {
41+
if len(this.eles) == 0 {
42+
return -1
43+
}
44+
45+
return this.eles[len(this.eles)-1]
46+
}
47+
48+
func (this *MinStack) GetMin() int {
49+
if len(this.minNums) == 0 {
50+
return -1
51+
}
52+
53+
return this.minNums[len(this.minNums)-1]
54+
}

algs/leetcode/21_mergeTwoLists.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package leetcode
2+
3+
// 23题的简化版,
4+
// 思路1:23题的小顶堆解法可以直接挪过来
5+
// 思路2,直接合并
6+
7+
func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode {
8+
head := &ListNode{Val: -1}
9+
10+
cur, cur1, cur2 := head, l1, l2
11+
for ; cur1 != nil && cur2 != nil; cur = cur.Next {
12+
if cur1.Val > cur2.Val {
13+
cur.Next = &ListNode{Val: cur2.Val}
14+
cur2 = cur2.Next
15+
} else {
16+
cur.Next = &ListNode{Val: cur1.Val}
17+
cur1 = cur1.Next
18+
}
19+
}
20+
21+
for ; cur1 != nil; cur = cur.Next {
22+
cur.Next = &ListNode{Val: cur1.Val}
23+
cur1 = cur1.Next
24+
}
25+
26+
for ; cur2 != nil; cur = cur.Next {
27+
cur.Next = &ListNode{Val: cur2.Val}
28+
cur2 = cur2.Next
29+
}
30+
31+
return head.Next
32+
}
33+
34+
func mergeTwoLists1(l1 *ListNode, l2 *ListNode) *ListNode {
35+
head := &ListNode{Val: -1}
36+
37+
cur, cur1, cur2 := head, l1, l2
38+
for ; cur1 != nil && cur2 != nil; cur = cur.Next {
39+
if cur1.Val > cur2.Val {
40+
cur.Next = &ListNode{Val: cur2.Val}
41+
cur2 = cur2.Next
42+
} else {
43+
cur.Next = &ListNode{Val: cur1.Val}
44+
cur1 = cur1.Next
45+
}
46+
}
47+
48+
if cur1 != nil {
49+
cur.Next = cur1
50+
}
51+
52+
if cur2 != nil {
53+
cur.Next = cur2
54+
}
55+
56+
return head.Next
57+
}

algs/leetcode/5311_numberOfSteps.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package leetcode
2+
3+
func numberOfSteps(num int) int {
4+
var f func(step, reminder int) int
5+
f = func(step, reminder int) int {
6+
if reminder == 0 {
7+
return step
8+
}
9+
10+
step++
11+
if (reminder & 0x01) == 0 {
12+
return f(step, reminder>>1)
13+
} else {
14+
return f(step, reminder-1)
15+
}
16+
}
17+
18+
return f(0, num)
19+
}

algs/leetcode/641_designDeque.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -108,16 +108,16 @@ type ListNode2 struct {
108108
}
109109

110110
/** Initialize your data structure here. Set the size of the deque to be k. */
111-
func Constructor(k int) MyCircularDeque {
112-
node := &ListNode2{Val: -1}
113-
node.Next = node
114-
node.Pre = node
115-
return MyCircularDeque{
116-
len: 0,
117-
cap: k,
118-
dummyNode: node,
119-
}
120-
}
111+
//func Constructor(k int) MyCircularDeque {
112+
// node := &ListNode2{Val: -1}
113+
// node.Next = node
114+
// node.Pre = node
115+
// return MyCircularDeque{
116+
// len: 0,
117+
// cap: k,
118+
// dummyNode: node,
119+
// }
120+
//}
121121

122122
/** Adds an item at the front of Deque. Return true if the operation is successful. */
123123
func (this *MyCircularDeque) InsertFront(value int) bool {
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package leetcode
2+
3+
import "strings"
4+
5+
func letterCasePermutation(S string) []string {
6+
ans := make([]string, 0, 2)
7+
S = strings.ToLower(S)
8+
9+
var backtrace func(pos int, cur []byte)
10+
backtrace = func(pos int, cur []byte) {
11+
if len(cur) == len(S) {
12+
ans = append(ans, string(cur))
13+
return
14+
}
15+
16+
if S[pos] >= 'a' && S[pos] <= 'z' {
17+
for i := 0; i < 2; i++ {
18+
cur = append(cur, S[pos]-uint8(32*i))
19+
backtrace(pos+1, cur)
20+
cur = cur[:len(cur)-1]
21+
}
22+
} else {
23+
cur = append(cur, S[pos])
24+
backtrace(pos+1, cur)
25+
}
26+
}
27+
28+
cur := make([]byte, 0, len(S))
29+
backtrace(0, cur)
30+
return ans
31+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package leetcode
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
)
7+
8+
func TestLetterCasePermutation(t *testing.T) {
9+
S := "a1b2"
10+
ans := letterCasePermutation(S)
11+
12+
fmt.Println(len(ans))
13+
fmt.Println(ans)
14+
}

algs/leetcode/78_subsets.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,30 @@ func subsets(nums []int) [][]int {
2121
}
2222

2323
for i := 0; i <= len(nums); i++ {
24-
cur := make([]int, 0, len(nums))
24+
cur := make([]int, 0, i)
2525
backtrace(0, i, cur)
2626
}
2727

2828
return ans
2929
}
30+
31+
// 动态规划:
32+
// 初始状态:dp[0]=[[]];
33+
// dp[i+1]={dp[i],[dp[i],nums[i-1]]}
34+
// FIXME 参考解法
35+
func subsets1(nums []int) [][]int {
36+
result := make([][]int, 0)
37+
result = append(result, []int{})
38+
39+
//遍历nums中的数,每遍历到一个就将该值依次添加到前面的所有子集中,形成新的子集
40+
for i := 0; i < len(nums); i++ {
41+
l := len(result)
42+
for j := 0; j < l; j++ {
43+
tmp := make([]int, 0)
44+
tmp = append(tmp, result[j]...)
45+
tmp = append(tmp, nums[i])
46+
result = append(result, tmp)
47+
}
48+
}
49+
return result
50+
}

algs/leetcode/90_subsetsWithDup.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package leetcode
2+
3+
import "sort"
4+
5+
func subsetsWithDup(nums []int) [][]int {
6+
ans := make([][]int, 0)
7+
sort.Ints(nums)
8+
9+
var backtrace func(pos, num int, cur []int)
10+
backtrace = func(pos, num int, cur []int) {
11+
if len(cur) == num {
12+
tmp := make([]int, len(cur))
13+
copy(tmp, cur)
14+
ans = append(ans, tmp)
15+
return
16+
}
17+
18+
for i := pos; i < len(nums); i++ {
19+
// 前面那个重复元素已经使用,则不再使用,在78题的基础上面剪枝
20+
if i > pos && nums[i] == nums[i-1] {
21+
continue
22+
}
23+
24+
cur = append(cur, nums[i])
25+
backtrace(i+1, num, cur)
26+
cur = cur[:len(cur)-1]
27+
}
28+
}
29+
30+
for i := 0; i <= len(nums); i++ {
31+
cur := make([]int, 0, i)
32+
backtrace(0, i, cur)
33+
}
34+
35+
return ans
36+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package leetcode
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
)
7+
8+
func TestSubsetsWithDup(t *testing.T) {
9+
nums := []int{1, 2, 2, 3}
10+
ans := subsetsWithDup(nums)
11+
12+
fmt.Println(len(ans))
13+
fmt.Println(ans)
14+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy