100% signifies that run time used to beat 100.00% of users.
Array / Hashing
func containsDuplicate(nums []int) bool {
hs := make(map[int]bool, len(nums))
for _, n := range nums {
if hs[n] {
return true
}
hs[n] = true
}
return false
}
- 242. Valid Anagram (100%)
func isAnagram(s string, t string) bool {
ls, lt := len(s), len(t)
if ls != lt {
return false
}
ctr := make([]int, 26)
for i := 0; i < ls; i++{
ctr[s[i] - 'a']++
ctr[t[i] - 'a']--
}
for _, v := range ctr {
if v != 0 {
return false
}
}
return true
}
- 1. Two Sum (100%)
func twoSum(nums []int, target int) []int {
hm := make(map[int]int, len(nums))
for i, v := range nums {
if value, ok := hm[target - v]; ok {
return []int{value, i}
}
hm[v] = i
}
return []int{-1}
}
func groupAnagrams(strs []string) [][]string {
hm := make(map[string][]string)
for _, s := range strs {
runes := []rune(s)
sort.Slice(runes, func(i int, j int) bool {
return runes[i] < runes[j]
})
key := string(runes)
hm[key] = append(hm[key], s)
}
ans := make([][]string, 0)
for _, v := range hm {
ans = append(ans, v)
}
return ans
}
- 347. Top K Frequent Elements (100%)
func topKFrequent(nums []int, k int) []int {
hm := make(map[int]int, len(nums))
for _, v := range nums {
hm[v] += 1
}
ctr := make([][]int, 0)
for k, v := range hm {
ctr = append(ctr, []int{k, v})
}
sort.Slice(ctr, func(i int, j int) bool {
return ctr[i][1] > ctr[j][1]
})
ans := make([]int, k)
for i := 0; i < k; i++ {
ans[i] = ctr[i][0]
}
return ans
}
func productExceptSelf(nums []int) []int {
n := len(nums)
ans := make([]int, n)
for i := 0; i < n; i++ {
ans[i] = 1
}
prefix := 1
for i := 0; i < n; i++ {
ans[i] *= prefix
prefix *= nums[i]
}
suffix := 1
for i := n - 1; i > -1; i-- {
ans[i] *= suffix
suffix *= nums[i]
}
return ans
}
type Codec struct {
}
func (codec *Codec) Encode(strs []string) string {
return strings.Join(strs, "%$$$$$")
}
func (codec *Codec) Decode(strs string) []string {
return strings.Split(strs, "%$$$$$")
}
func longestConsecutive(nums []int) int {
hs, mx := make(map[int]bool, len(nums)), 0
for _, n := range nums {
hs[n] = true
}
for n := range hs {
if !hs[n - 1] {
ln := 1
for hs[n + ln] {
ln++
}
mx = max(mx, ln)
}
}
return mx
}
Two Pointers
- 125. Valid Palindrome (100%)
func isPalindrome(s string) bool {
s = strings.Map(func(r rune) rune {
if !unicode.IsLetter(r) && !unicode.IsNumber(r){
return -1
}
return unicode.ToLower(r)
}, s)
l, r := 0, len(s) - 1
for l < r {
if s[l] != s[r] {
return false
}
l++
r--
}
return true
}
func threeSum(nums []int) [][]int {
sort.Slice(nums, func(i, j int) bool {
return nums[i] < nums[j]
})
ans := make([][]int, 0)
ln := len(nums)
for i, v := range nums {
if i > 0 && nums[i - 1] == v {
continue
}
l := i + 1
r := ln - 1
for l < r {
sm := v + nums[l] + nums[r]
if sm > 0 {
r--
} else if sm < 0 {
l++
} else {
ans = append(ans, []int{v, nums[l], nums[r]})
l++
for l < r && nums[l - 1] == nums[l] {
l++
}
}
}
}
return ans
}
func maxArea(height []int) int {
l, r, mx := 0, len(height) - 1, 0
for l < r {
lh, rh := height[l], height[r]
mx = max(mx, min(lh, rh) * (r - l))
if lh < rh {
l++
} else {
r--
}
}
return mx
}
Sliding Window
func maxProfit(prices []int) int {
l, mx := 0, 0
for r := range prices {
pl, pr := prices[l], prices[r]
if pl >= pr {
l = r
}
mx = max(mx, pr - pl)
}
return mx
}
func lengthOfLongestSubstring(s string) int {
l, mx, hm := 0, 0, make(map[rune]int, len(s))
for r, v := range s {
if value, ok := hm[v]; ok {
l = max(l, value + 1)
}
hm[v] = r
mx = max(mx, r - l + 1)
}
return mx
}
func characterReplacement(s string, k int) int {
l, mx, n := 0, 0, len(s)
hm := make(map[rune]int, n)
for r, v := range []rune(s) {
hm[v]++
mx = max(mx, hm[v])
if r - l + 1 - mx > k {
hm[rune(s[l])]--
l++
}
}
return n - l
}
func minWindow(s string, t string) string {
cs, ct := make(map[rune]int), make(map[rune]int)
for _, c := range t {
ct[c]++
}
have, need := 0, len(ct)
mn := math.MaxInt
start, end := 0, -1
l := 0
for r, c := range s {
cs[c]++
if cs[c] == ct[c] {
have++
}
for have == need {
if mn > r - l + 1 {
mn = r - l + 1
start = l
end = r
}
cs[rune(s[l])]--
if cs[rune(s[l])] < ct[rune(s[l])] {
have--
}
l++
}
}
return s[start: end + 1]
}
Stack
- 20. Valid Parentheses (100%)
func isValid(s string) bool {
hm := map[rune]rune{
')': '(',
']': '[',
'}': '{',
}
stack := make([]rune, 0)
for _, v := range s {
n := len(stack)
if n > 0 && stack[n - 1] == hm[v] {
stack = stack[: n - 1]
} else {
stack = append(stack, v)
}
}
return len(stack) == 0
}
Binary Search
func findMin(nums []int) int {
l, r := 0, len(nums) - 1
for l < r {
m := (l + r) / 2
if nums[m] > nums[r] {
l = m + 1
} else {
r = m
}
}
return nums[l]
}
func search(nums []int, target int) int {
l, r := 0, len(nums) - 1
for l <= r {
m := (l + r) / 2
if target < nums[m] {
if nums[l] > nums[m] || target >= nums[l] {
r = m - 1
} else {
l = m + 1
}
} else if target > nums[m] {
if nums[m] > nums[r] || target <= nums[r] {
l = m + 1
} else {
r = m - 1
}
} else {
return m
}
}
return -1
}
Linked List
- 206. Reverse Linked List (100%)
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func reverseList(head *ListNode) *ListNode {
crt := head
var prev *ListNode
for crt != nil {
nxt := crt.Next
crt.Next = prev
prev = crt
crt = nxt
}
return prev
}
- 21. Merge Two Sorted Lists (100%)
func mergeTwoLists(list1 *ListNode, list2 *ListNode) *ListNode {
l, r := list1, list2
dummy := &ListNode{}
crt := dummy
for l != nil && r != nil {
if l.Val < r.Val {
crt.Next = l
l = l.Next
} else {
crt.Next = r
r = r.Next
}
crt = crt.Next
}
if l != nil {
crt.Next = l
}
if r != nil {
crt.Next = r
}
return dummy.Next
}
- 143. Reorder List (100%)
func reorderList(head *ListNode) {
s, f := head, head.Next
for f != nil && f.Next != nil {
s = s.Next
f = f.Next.Next
}
var prev *ListNode
crt := s.Next
s.Next = nil
for crt != nil {
nxt := crt.Next
crt.Next = prev
prev = crt
crt = nxt
}
l, r := head, prev
dummy := &ListNode{}
crt = dummy
for l != nil && r != nil {
crt.Next = l
l = l.Next
crt = crt.Next
crt.Next = r
r = r.Next
crt = crt.Next
}
if l != nil {
crt.Next = l
}
}
func removeNthFromEnd(head *ListNode, n int) *ListNode {
dummy := &ListNode{Next: head}
crt := head
for n > 0 {
crt = crt.Next
n--
}
l, r := dummy, crt
for r != nil {
l = l.Next
r = r.Next
}
l.Next = l.Next.Next
return dummy.Next
}
- 141. Linked List Cycle (100%)
func hasCycle(head *ListNode) bool {
s, f := head, head
for f != nil && f.Next != nil {
s = s.Next
f = f.Next.Next
if s == f {
return true
}
}
return false
}
- 23. Merge k Sorted Lists (100%)
func mergeKLists(lists []*ListNode) *ListNode {
if len(lists) == 0 {
return nil
}
for len(lists) > 1 {
merged := make([]*ListNode, 0)
for i := 0; i < len(lists); i += 2 {
l := lists[i]
r := &ListNode{}
if i + 1 < len(lists) {
r = lists[i + 1]
} else {
r = nil
}
merged = append(merged, merge(l, r))
}
lists = merged
}
return lists[0]
}
func merge(l *ListNode, r *ListNode) *ListNode {
dummy := &ListNode{}
crt := dummy
for l != nil && r != nil {
if l.Val < r.Val {
crt.Next = l
l = l.Next
} else {
crt.Next = r
r = r.Next
}
crt = crt.Next
}
if l != nil {
crt.Next = l
}
if r != nil {
crt.Next = r
}
return dummy.Next
}
Insights
- Declare a map with a size will improve efficiency
- Loop by rune seems faster than by byte