diff --git a/src/0001_two_sum/twosum.go b/src/0001_two_sum/twosum.go new file mode 100644 index 0000000..c3b8014 --- /dev/null +++ b/src/0001_two_sum/twosum.go @@ -0,0 +1,34 @@ +/* +1. Two Sum + +Source: https://leetcode.com/problems/two-sum/ + +Given an array of integers, return indices of the two numbers such that they add up to a specific target. + +You may assume that each input would have exactly one solution, and you may not use the same element twice. + +Example: + +Given nums = [2, 7, 11, 15], target = 9, + +Because nums[0] + nums[1] = 2 + 7 = 9, +return [0, 1]. + +*/ + +package twosum + +// Time complexity: O(n) +// Space complexity: O(n) +func twoSum(nums []int, target int) []int { + record := make(map[int]int) + + for i, j := range nums { + complement := target - j + if res, ok := record[complement]; ok { + return []int{res, i} + } + record[j] = i + } + return []int{} +} diff --git a/src/0001_two_sum/twosum_test.go b/src/0001_two_sum/twosum_test.go new file mode 100644 index 0000000..7d23e52 --- /dev/null +++ b/src/0001_two_sum/twosum_test.go @@ -0,0 +1,18 @@ +package twosum + +import ( + "reflect" + "testing" +) + +func TestTwoSum(t *testing.T) { + nums := []int{2, 7, 11, 15} + + if res := twoSum(nums, 9); !reflect.DeepEqual(res, []int{0, 1}) { + t.Error("Failed, two sum") + } + + if res := twoSum(nums, 6); !reflect.DeepEqual(res, []int{}) { + t.Error("Failed, two sum") + } +} diff --git a/src/0002_add_two_numbers/add_two_numbers.go b/src/0002_add_two_numbers/add_two_numbers.go new file mode 100644 index 0000000..a1befa1 --- /dev/null +++ b/src/0002_add_two_numbers/add_two_numbers.go @@ -0,0 +1,96 @@ +/* +2. Add Two Numbers + +Source: https://leetcode.com/problems/add-two-numbers/ + +You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. + +You may assume the two numbers do not contain any leading zero, except the number 0 itself. + +Example: + +Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) +Output: 7 -> 0 -> 8 +Explanation: 342 + 465 = 807. +*/ + +package addtwonumbers + +// ListNode is node of linked list +type ListNode struct { + Val int + Next *ListNode +} + +// 解法一,暴力解法 +func addTwoNumbers1(l1 *ListNode, l2 *ListNode) *ListNode { + head := ListNode{Val: -1} + cur := &head + carry := 0 + for l1 != nil && l2 != nil { + sum := l1.Val + l2.Val + carry + val := sum % 10 + carry = sum / 10 + node := ListNode{Val: val} + cur.Next = &node + cur = cur.Next + l1 = l1.Next + l2 = l2.Next + } + if carry == 0 { + if l1 != nil { + cur.Next = l1 + } + if l2 != nil { + cur.Next = l2 + } + return head.Next + } + for l1 != nil { + sum := l1.Val + carry + val := sum % 10 + carry = sum / 10 + node := ListNode{Val: val} + cur.Next = &node + cur = cur.Next + l1 = l1.Next + } + for l2 != nil { + sum := l2.Val + carry + val := sum % 10 + carry = sum / 10 + node := ListNode{Val: val} + cur.Next = &node + cur = cur.Next + l2 = l2.Next + } + for carry != 0 { + val := carry % 10 + carry = carry / 10 + node := ListNode{Val: val} + cur.Next = &node + cur = cur.Next + } + return head.Next +} + +// 解法二,递归 +func addTwoNumbers2(l1 *ListNode, l2 *ListNode) *ListNode { + if l1 == nil && l2 == nil { + return nil + } else if l1 == nil && l2 != nil { + return l2 + } else if l1 != nil && l2 == nil { + return l1 + } + + sum := l1.Val + l2.Val + next := addTwoNumbers2(l1.Next, l2.Next) + + if sum >= 10 { + carry := sum / 10 + sum %= 10 + next = addTwoNumbers2(next, &ListNode{Val: carry}) + } + return &ListNode{Val: sum, Next: next} +} diff --git a/src/0002_add_two_numbers/add_two_numbers_test.go b/src/0002_add_two_numbers/add_two_numbers_test.go new file mode 100644 index 0000000..9ac5804 --- /dev/null +++ b/src/0002_add_two_numbers/add_two_numbers_test.go @@ -0,0 +1,130 @@ +package addtwonumbers + +import ( + "os" + "reflect" + "testing" +) + +func createSingleLinkedList(arr []int) *ListNode { + head := &ListNode{} + cur := head + + for _, j := range arr { + cur.Next = &ListNode{Val: j} + cur = cur.Next + } + return head.Next +} + +func TestAddTwoNumbers1(t *testing.T) { + testDatas := []struct { + name string + arg1 *ListNode + arg2 *ListNode + expected *ListNode + }{ + { + name: "one", + arg1: createSingleLinkedList([]int{2, 4, 3}), + arg2: createSingleLinkedList([]int{5, 6, 4}), + expected: createSingleLinkedList([]int{7, 0, 8}), + }, + { + name: "two", + arg1: createSingleLinkedList([]int{5}), + arg2: createSingleLinkedList([]int{5}), + expected: createSingleLinkedList([]int{0, 1}), + }, + { + name: "three", + arg1: createSingleLinkedList([]int{1}), + arg2: createSingleLinkedList([]int{9, 9, 9}), + expected: createSingleLinkedList([]int{0, 0, 0, 1}), + }, + { + name: "four", + arg1: createSingleLinkedList([]int{9, 9, 9}), + arg2: createSingleLinkedList([]int{1}), + expected: createSingleLinkedList([]int{0, 0, 0, 1}), + }, + { + name: "five", + arg1: createSingleLinkedList([]int{4, 3, 1}), + arg2: createSingleLinkedList([]int{1}), + expected: createSingleLinkedList([]int{5, 3, 1}), + }, + { + name: "six", + arg1: createSingleLinkedList([]int{1}), + arg2: createSingleLinkedList([]int{4, 3, 1}), + expected: createSingleLinkedList([]int{5, 3, 1}), + }, + } + + for _, testData := range testDatas { + t.Run(testData.name, func(t *testing.T) { + if result := addTwoNumbers1(testData.arg1, testData.arg2); !reflect.DeepEqual(result, testData.expected) { + t.Errorf("expected %v, got %v", testData.expected, result) + } + }) + } +} + +func TestAddTwoNumbers2(t *testing.T) { + testDatas := []struct { + name string + arg1 *ListNode + arg2 *ListNode + expected *ListNode + }{ + { + name: "one", + arg1: createSingleLinkedList([]int{2, 4, 3}), + arg2: createSingleLinkedList([]int{5, 6, 4}), + expected: createSingleLinkedList([]int{7, 0, 8}), + }, + { + name: "two", + arg1: createSingleLinkedList([]int{5}), + arg2: createSingleLinkedList([]int{5}), + expected: createSingleLinkedList([]int{0, 1}), + }, + { + name: "three", + arg1: createSingleLinkedList([]int{1}), + arg2: createSingleLinkedList([]int{9, 9, 9}), + expected: createSingleLinkedList([]int{0, 0, 0, 1}), + }, + { + name: "four", + arg1: createSingleLinkedList([]int{9, 9, 9}), + arg2: createSingleLinkedList([]int{1}), + expected: createSingleLinkedList([]int{0, 0, 0, 1}), + }, + { + name: "five", + arg1: createSingleLinkedList([]int{4, 3, 1}), + arg2: createSingleLinkedList([]int{1}), + expected: createSingleLinkedList([]int{5, 3, 1}), + }, + { + name: "six", + arg1: createSingleLinkedList([]int{1}), + arg2: createSingleLinkedList([]int{4, 3, 1}), + expected: createSingleLinkedList([]int{5, 3, 1}), + }, + } + + for _, testData := range testDatas { + t.Run(testData.name, func(t *testing.T) { + if result := addTwoNumbers2(testData.arg1, testData.arg2); !reflect.DeepEqual(result, testData.expected) { + t.Errorf("expected %v, got %v", testData.expected, result) + } + }) + } +} + +func TestMain(m *testing.M) { + os.Exit(m.Run()) +} diff --git a/src/0003_longest_substring_without_repeating_characters/longest_substring_without_repeating_characters.go b/src/0003_longest_substring_without_repeating_characters/longest_substring_without_repeating_characters.go new file mode 100644 index 0000000..80a116b --- /dev/null +++ b/src/0003_longest_substring_without_repeating_characters/longest_substring_without_repeating_characters.go @@ -0,0 +1,48 @@ +/* +3. Longest Substring Without Repeating Characters + +Source: https://leetcode.com/problems/longest-substring-without-repeating-characters/ + +Given a string, find the length of the longest substring without repeating characters. + +Example 1: + +Input: "abcabcbb" +Output: 3 +Explanation: The answer is "abc", with the length of 3. +Example 2: + +Input: "bbbbb" +Output: 1 +Explanation: The answer is "b", with the length of 1. +Example 3: + +Input: "pwwkew" +Output: 3 +Explanation: The answer is "wke", with the length of 3. + Note that the answer must be a substring, "pwke" is a subsequence and not a substring. +*/ + +package longestsubstringwithoutrepeatingcharacters + +// Time complexity: O(n) +// Space complexity: O(n) +func lengthOfLongestSubstring(s string) int { + + var ( + start = 0 + res = 0 + lastOccurredRecord = make(map[rune]int) + ) + + for i, ch := range []rune(s) { + if lastIndex, ok := lastOccurredRecord[ch]; ok && lastIndex >= start { + start = lastIndex + 1 + } + if i-start+1 > res { + res = i - start + 1 + } + lastOccurredRecord[ch] = i + } + return res +} diff --git a/src/0003_longest_substring_without_repeating_characters/longest_substring_without_repeating_characters_test.go b/src/0003_longest_substring_without_repeating_characters/longest_substring_without_repeating_characters_test.go new file mode 100644 index 0000000..01206b1 --- /dev/null +++ b/src/0003_longest_substring_without_repeating_characters/longest_substring_without_repeating_characters_test.go @@ -0,0 +1,18 @@ +package longestsubstringwithoutrepeatingcharacters + +import "testing" + +func TestLengthOfLongestSubstring(t *testing.T) { + testData := []string{ + "abcabcbb", + "bbbbb", + "pwwkew", + } + expectedData := []int{3, 1, 3} + + for index, data := range testData { + if res := lengthOfLongestSubstring(data); res != expectedData[index] { + t.Errorf("expected %d, got %d", expectedData[index], res) + } + } +} diff --git a/src/0017_letter_combination_of_a_phone_number/letter_combination_of_phone_number.go b/src/0017_letter_combination_of_a_phone_number/letter_combination_of_phone_number.go new file mode 100644 index 0000000..1f6b308 --- /dev/null +++ b/src/0017_letter_combination_of_a_phone_number/letter_combination_of_phone_number.go @@ -0,0 +1,61 @@ +/* +17. Letter Combinations of a Phone Number + +Source: https://leetcode.com/problems/letter-combinations-of-a-phone-number/ + +Given a string containing digits from 2-9 inclusive, return all possible letter combinations that the number could represent. + +A mapping of digit to letters (just like on the telephone buttons) is given below. Note that 1 does not map to any letters. + +Example: + +Input: "23" +Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]. +Note: + +Although the above answer is in lexicographical order, your answer could be in any order you want. +*/ + +package lettercombinationsofaphonenumber + +var ( + letterMap = []string{ + " ", + "", + "abc", + "def", + "ghi", + "jkl", + "mno", + "pqrs", + "tuv", + "wxyz", + } + res []string +) + +// Time complexity: O(2^n) +// Space complexity: O(n) +func letterCombinations(digits string) []string { + res = []string{} + if digits == "" { + return res + } + + findCombinations(digits, 0, "") + return res +} + +func findCombinations(digits string, index int, s string) { + if index == len(digits) { + res = append(res, s) + return + } + + ch := digits[index] + letters := letterMap[ch-'0'] + for _, i := range letters { + findCombinations(digits, index+1, s+string(i)) + } + return +} diff --git a/src/0017_letter_combination_of_a_phone_number/letter_combination_of_phone_number_test.go b/src/0017_letter_combination_of_a_phone_number/letter_combination_of_phone_number_test.go new file mode 100644 index 0000000..fb204d5 --- /dev/null +++ b/src/0017_letter_combination_of_a_phone_number/letter_combination_of_phone_number_test.go @@ -0,0 +1,24 @@ +package lettercombinationsofaphonenumber + +import ( + "reflect" + "testing" +) + +func TestLetterCombinations(t *testing.T) { + testData := []string{ + "23", + "", + } + + expectedData := [][]string{ + []string{"ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"}, + []string{}, + } + + for index, digits := range testData { + if res := letterCombinations(digits); !reflect.DeepEqual(res, expectedData[index]) { + t.Errorf("expected %v, got %v", expectedData[index], res) + } + } +} diff --git a/src/0020_valid_parentheses/valid_parentheses.go b/src/0020_valid_parentheses/valid_parentheses.go new file mode 100644 index 0000000..5a692f0 --- /dev/null +++ b/src/0020_valid_parentheses/valid_parentheses.go @@ -0,0 +1,66 @@ +/* +20. Valid Parentheses + +Source: https://leetcode.com/problems/valid-parentheses/ + +Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. + +An input string is valid if: + + 1. Open brackets must be closed by the same type of brackets. + 2. Open brackets must be closed in the correct order. + +Note that an empty string is also considered valid. + +Example 1: + +Input: "()" +Output: true +Example 2: + +Input: "()[]{}" +Output: true +Example 3: + +Input: "(]" +Output: false +Example 4: + +Input: "([)]" +Output: false +Example 5: + +Input: "{[]}" +Output: true +*/ + +package validparentheses + +// Time complexity: O(n) +// Space complexity: O(n) +func isValid(s string) bool { + var ( + stacks []rune + mapping = map[rune]rune{')': '(', ']': '[', '}': '{'} + ) + for _, char := range s { + if char == ')' || char == '}' || char == ']' { + var topElement rune + if len(stacks) > 0 { + topElement = stacks[len(stacks)-1] + stacks = stacks[:len(stacks)-1] + } else { + topElement = '#' + } + if mapping[char] != topElement { + return false + } + } else { + stacks = append(stacks, char) + } + } + if len(stacks) > 0 { + return false + } + return true +} diff --git a/src/0020_valid_parentheses/valid_parentheses_test.go b/src/0020_valid_parentheses/valid_parentheses_test.go new file mode 100644 index 0000000..e3b6147 --- /dev/null +++ b/src/0020_valid_parentheses/valid_parentheses_test.go @@ -0,0 +1,15 @@ +package validparentheses + +import "testing" + +func TestIsValid(t *testing.T) { + testData := []string{"()", "(((((())))))", "()()()()", "(((((((()", "((()(())))", "", ")(", "}{", "][", "(][)"} + expectedData := []bool{true, true, true, false, true, true, false, false, false, false} + + for i, s := range testData { + result := isValid(s) + if result != expectedData[i] { + t.Error("测试不通过") + } + } +} diff --git a/src/0021_merge_two_sorted_lists/mergeTwoLists.go b/src/0021_merge_two_sorted_lists/mergeTwoLists.go new file mode 100644 index 0000000..21836ac --- /dev/null +++ b/src/0021_merge_two_sorted_lists/mergeTwoLists.go @@ -0,0 +1,42 @@ +/* +21. Merge Two Sorted Lists +Source: https://leetcode.com/problems/merge-two-sorted-lists/ + +Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists. + +Example: + +Input: 1->2->4, 1->3->4 +Output: 1->1->2->3->4->4 +*/ + +package mergetwolists + +// ListNode is node of linked list +type ListNode struct { + Val int + Next *ListNode +} + +// Recursion +// Time complexity: O(len(l1)+len(l2)) +// Space complexity: O(len(l1)+len(l2)) +func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode { + if l1 == nil && l2 == nil { + return nil + } + if l1 == nil { + return l2 + } + + if l2 == nil { + return l1 + } + + if l1.Val < l2.Val { + l1.Next = mergeTwoLists(l1.Next, l2) + return l1 + } + l2.Next = mergeTwoLists(l1, l2.Next) + return l2 +} diff --git a/src/0021_merge_two_sorted_lists/mergeTwoLists_test.go b/src/0021_merge_two_sorted_lists/mergeTwoLists_test.go new file mode 100644 index 0000000..a545bbe --- /dev/null +++ b/src/0021_merge_two_sorted_lists/mergeTwoLists_test.go @@ -0,0 +1,59 @@ +package mergetwolists + +import ( + "reflect" + "testing" +) + +func createSingleLinkedList(arr []int) *ListNode { + head := &ListNode{} + cur := head + + for _, j := range arr { + cur.Next = &ListNode{Val: j} + cur = cur.Next + } + return head.Next +} + +func TestMergeTwoLists(t *testing.T) { + testDatas := []struct { + name string + arg1 *ListNode + arg2 *ListNode + expected *ListNode + }{ + { + name: "one", + arg1: createSingleLinkedList([]int{1, 3, 5}), + arg2: createSingleLinkedList([]int{2, 4, 6}), + expected: createSingleLinkedList([]int{1, 2, 3, 4, 5, 6}), + }, + { + name: "two", + arg1: createSingleLinkedList([]int{1}), + arg2: createSingleLinkedList([]int{2, 4, 6}), + expected: createSingleLinkedList([]int{1, 2, 4, 6}), + }, + { + name: "three", + arg1: nil, + arg2: nil, + expected: nil, + }, + { + name: "four", + arg1: createSingleLinkedList([]int{2, 4, 6}), + arg2: createSingleLinkedList([]int{1}), + expected: createSingleLinkedList([]int{1, 2, 4, 6}), + }, + } + + for _, testData := range testDatas { + t.Run(testData.name, func(t *testing.T) { + if result := mergeTwoLists(testData.arg1, testData.arg2); !reflect.DeepEqual(result, testData.expected) { + t.Errorf("mergeTwoLists() = %v, expected %v", result, testData.expected) + } + }) + } +} diff --git a/src/0025_reverse_nodes_in_k_group/reverse_node_k_group.go b/src/0025_reverse_nodes_in_k_group/reverse_node_k_group.go new file mode 100644 index 0000000..203ba83 --- /dev/null +++ b/src/0025_reverse_nodes_in_k_group/reverse_node_k_group.go @@ -0,0 +1,75 @@ +/* +25. Reverse Nodes in k-Group + +Source: https://leetcode.com/problems/reverse-nodes-in-k-group/ + +Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. + +k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is. + +Example: + +Given this linked list: 1->2->3->4->5 + +For k = 2, you should return: 2->1->4->3->5 + +For k = 3, you should return: 3->2->1->4->5 + +Note: + Only constant extra memory is allowed. + You may not alter the values in the list's nodes, only nodes itself may be changed. +*/ + +package reversenodesinkgroup + +// ListNode is node of linked list +type ListNode struct { + Val int + Next *ListNode +} + +func reverseKGroup(head *ListNode, k int) *ListNode { + if head == nil || head.Next == nil || k < 2 { + return head + } + + p := new(ListNode) + s := new(ListNode) + l := k + p.Next = head + head = p + s = p + + for s != nil && k != 0 { + s = s.Next + k-- + } + + for s != nil { + reverse(&p, &s) + k = l + for s != nil && k != 0 { + s = s.Next + k-- + } + } + return head.Next +} + +func reverse(p **ListNode, s **ListNode) { + var tmp *ListNode + prev := (*p).Next + tail := (*p).Next + flag := (*s).Next + + (*p).Next = nil + for prev != flag { + tmp = (*p).Next + (*p).Next = prev + prev = prev.Next + (*p).Next.Next = tmp + } + tail.Next = prev + *p = tail + *s = tail +} diff --git a/src/0025_reverse_nodes_in_k_group/reverse_node_k_group_test.go b/src/0025_reverse_nodes_in_k_group/reverse_node_k_group_test.go new file mode 100644 index 0000000..4e5e0cb --- /dev/null +++ b/src/0025_reverse_nodes_in_k_group/reverse_node_k_group_test.go @@ -0,0 +1,62 @@ +package reversenodesinkgroup + +import ( + "reflect" + "testing" +) + +func createSingleLinkedList(arr []int) *ListNode { + head := &ListNode{} + cur := head + + for _, j := range arr { + cur.Next = &ListNode{Val: j} + cur = cur.Next + } + return head.Next +} + +func TestReverseKGroup(t *testing.T) { + type args struct { + head *ListNode + k int + } + tests := []struct { + name string + args args + expected *ListNode + }{ + { + name: "one", + args: args{ + head: createSingleLinkedList([]int{1, 2, 3, 4, 5}), + k: 2, + }, + expected: createSingleLinkedList([]int{2, 1, 4, 3, 5}), + }, + { + name: "two", + args: args{ + head: createSingleLinkedList([]int{1, 2, 3, 4, 5}), + k: 3, + }, + expected: createSingleLinkedList([]int{3, 2, 1, 4, 5}), + }, + + { + name: "three", + args: args{ + head: createSingleLinkedList([]int{1}), + k: 2, + }, + expected: createSingleLinkedList([]int{1}), + }, + } + for _, data := range tests { + t.Run(data.name, func(t *testing.T) { + if result := reverseKGroup(data.args.head, data.args.k); !reflect.DeepEqual(result, data.expected) { + t.Errorf("reverseKGroup() = %v, expected %v", result, data.expected) + } + }) + } +} diff --git a/src/0061_rotate_list/rotate_list.go b/src/0061_rotate_list/rotate_list.go new file mode 100644 index 0000000..48fe858 --- /dev/null +++ b/src/0061_rotate_list/rotate_list.go @@ -0,0 +1,71 @@ +/* +61. Rotate List + +Source: https://leetcode.com/problems/rotate-list/ + +Given a linked list, rotate the list to the right by k places, where k is non-negative. + +Example 1: + Input: 1->2->3->4->5->NULL, k = 2 + Output: 4->5->1->2->3->NULL + Explanation: + rotate 1 steps to the right: 5->1->2->3->4->NULL + rotate 2 steps to the right: 4->5->1->2->3->NULL + +Example 2: + Input: 0->1->2->NULL, k = 4 + Output: 2->0->1->NULL + rotate 1 steps to the right: 2->0->1->NULL + Explanation: + rotate 2 steps to the right: 1->2->0->NULL + otate 3 steps to the right: 0->1->2->NULL + rotate 4 steps to the right: 2->0->1->NULL +*/ + +package rotatelist + +// ListNode is node of linked list +type ListNode struct { + Val int + Next *ListNode +} + +func rotateRight(head *ListNode, k int) *ListNode { + if k == 0 || head == nil || head.Next == nil { + return head + } + + var ( + listSize int + count int + p = head + rotateNode = head + ) + + for p != nil && count < k { + p = p.Next + listSize++ + count++ + } + + if p == nil { + k = k % listSize + if k == 0 { + return head + } + p = head + for count = 0; count < k; count++ { + p = p.Next + } + } + + for p.Next != nil { + rotateNode = rotateNode.Next + p = p.Next + } + + p.Next = head + head = rotateNode.Next + rotateNode.Next = nil + return head +} diff --git a/src/0061_rotate_list/rotate_list_test.go b/src/0061_rotate_list/rotate_list_test.go new file mode 100644 index 0000000..24cc98b --- /dev/null +++ b/src/0061_rotate_list/rotate_list_test.go @@ -0,0 +1,71 @@ +package rotatelist + +import ( + "reflect" + "testing" +) + +func createSingleLinkedList(arr []int) *ListNode { + head := &ListNode{} + cur := head + + for _, j := range arr { + cur.Next = &ListNode{Val: j} + cur = cur.Next + } + return head.Next +} + +func TestRotateList(t *testing.T) { + testDatas := []struct { + name string + arg *ListNode + k int + expected *ListNode + }{ + { + name: "one", + arg: createSingleLinkedList([]int{1, 2, 3, 4}), + k: 2, + expected: createSingleLinkedList([]int{3, 4, 1, 2}), + }, + { + name: "two", + arg: createSingleLinkedList([]int{1, 2, 3}), + k: 3, + expected: createSingleLinkedList([]int{1, 2, 3}), + }, + { + name: "three", + arg: createSingleLinkedList([]int{1, 2, 3}), + k: 5, + expected: createSingleLinkedList([]int{2, 3, 1}), + }, + { + name: "four", + arg: createSingleLinkedList([]int{1, 2, 3}), + k: 0, + expected: createSingleLinkedList([]int{1, 2, 3}), + }, + { + name: "five", + arg: nil, + k: 0, + expected: nil, + }, + { + name: "four", + arg: createSingleLinkedList([]int{1}), + k: 5, + expected: createSingleLinkedList([]int{1}), + }, + } + + for _, testData := range testDatas { + t.Run(testData.name, func(t *testing.T) { + if result := rotateRight(testData.arg, testData.k); !reflect.DeepEqual(result, testData.expected) { + t.Errorf("expected %v, got %v", testData.expected, result) + } + }) + } +} diff --git a/src/0062_unique_paths/unique_paths.go b/src/0062_unique_paths/unique_paths.go new file mode 100644 index 0000000..88acd6e --- /dev/null +++ b/src/0062_unique_paths/unique_paths.go @@ -0,0 +1,87 @@ +/* +62. Unique Paths +Source: https://leetcode.com/problems/unique-paths/ + +A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). + +The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below). + +How many possible unique paths are there? + + +Above is a 7 x 3 grid. How many possible unique paths are there? + +Note: m and n will be at most 100. + +Example 1: + +Input: m = 3, n = 2 +Output: 3 +Explanation: +From the top-left corner, there are a total of 3 ways to reach the bottom-right corner: +1. Right -> Right -> Down +2. Right -> Down -> Right +3. Down -> Right -> Right +Example 2: + +Input: m = 7, n = 3 +Output: 28 +*/ + +package uniquepaths + +// recursion +/* +func uniquePaths(m int, n int) int { + if m == 1 || n == 1 { + return 1 + } + return uniquePaths(m, n-1) + uniquePaths(m-1, n) +} +*/ + +// memory search +/* +func uniquePaths(m int, n int) int { + memo := make([][]int, m) // memo[i][j]存储(i+1)*(j+1)grid的路径数量 + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + memo[i] = append(memo[i], -1) + } + } + return calcPaths(m, n, memo) +} + +func calcPaths(m int, n int, memo [][]int) int { + if memo[m-1][n-1] != -1 { + return memo[m-1][n-1] + } + + if m == 1 || n == 1 { + memo[m-1][n-1] = 1 + return 1 + } + + res := calcPaths(m, n-1, memo) + calcPaths(m-1, n, memo) + memo[m-1][n-1] = res + return res +} +*/ + +func uniquePaths(m int, n int) int { + memo := make([][]int, m) // memo[i][j]存储(i+1)*(j+1)grid的路径数量 + for i := 0; i < m; i++ { + memo[i] = append(memo[i], 1) + } + + for i := 1; i < n; i++ { + memo[0] = append(memo[0], 1) + } + + for i := 1; i < m; i++ { + for j := 1; j < n; j++ { + memo[i] = append(memo[i], memo[i-1][j]+memo[i][j-1]) + } + } + return memo[m-1][n-1] +} diff --git a/src/0062_unique_paths/unique_paths_test.go b/src/0062_unique_paths/unique_paths_test.go new file mode 100644 index 0000000..0ac72d7 --- /dev/null +++ b/src/0062_unique_paths/unique_paths_test.go @@ -0,0 +1,19 @@ +package uniquepaths + +import "testing" + +func TestUniquePaths(t *testing.T) { + testData := [][2]int{ + {3, 2}, + {51, 9}, + {9, 9}, + } + + expectedData := []int{3, 1916797311, 12870} + + for index, data := range testData { + if res := uniquePaths(data[0], data[1]); res != expectedData[index] { + t.Errorf("expected %d, got %d", expectedData[index], res) + } + } +} diff --git a/src/0063_unique_paths_2/unique_paths2.go b/src/0063_unique_paths_2/unique_paths2.go new file mode 100644 index 0000000..fe4d886 --- /dev/null +++ b/src/0063_unique_paths_2/unique_paths2.go @@ -0,0 +1,157 @@ +/* +63. Unique Paths II + +Source: https://leetcode.com/problems/unique-paths-ii/ + +A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). + +The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below). + +Now consider if some obstacles are added to the grids. How many unique paths would there be? + + + +An obstacle and empty space is marked as 1 and 0 respectively in the grid. + +Note: m and n will be at most 100. + +Example 1: + +Input: +[ + [0,0,0], + [0,1,0], + [0,0,0] +] +Output: 2 +Explanation: +There is one obstacle in the middle of the 3x3 grid above. +There are two ways to reach the bottom-right corner: +1. Right -> Right -> Down -> Down +2. Down -> Down -> Right -> Right +*/ + +package uniquepaths2 + +// recursion +/* +func uniquePathsWithObstacles(obstacleGrid [][]int) int { + m := len(obstacleGrid) + n := len(obstacleGrid[0]) + + cur := 1 + if m == 1 { + for i := 0; i < n; i++ { + if obstacleGrid[0][i] == 1 { + cur = 0 + } + } + return cur + } + + cur = 1 + if n == 1 { + for i := 0; i < m; i++ { + if obstacleGrid[i][0] == 1 { + cur = 0 + } + } + return cur + } + if obstacleGrid[m-1][n-1] == 1 { + return 0 + } + + obstacleGridCut := make([][]int, m) + + for i := range obstacleGridCut { + for j := 0; j < n-1; j++ { + obstacleGridCut[i] = append(obstacleGridCut[i], obstacleGrid[i][j]) + } + } + + return uniquePathsWithObstacles(obstacleGrid[:m-1]) + uniquePathsWithObstacles(obstacleGridCut) +} +*/ + +// memory search +/* +func uniquePathsWithObstacles(obstacleGrid [][]int) int { + m := len(obstacleGrid) + n := len(obstacleGrid[0]) + + memo := make([][]int, m) + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + memo[i] = append(memo[i], -1) + } + } + + cur := 1 + for i := 0; i < m; i++ { + if obstacleGrid[i][0] == 1 { + cur = 0 + } + memo[i][0] = cur + } + + cur = 1 + for j := 0; j < n; j++ { + if obstacleGrid[0][j] == 1 { + cur = 0 + } + memo[0][j] = cur + } + return calcUniquePaths(obstacleGrid, m-1, n-1, memo) +} + +func calcUniquePaths(obstacleGrid [][]int, m int, n int, memo [][]int) int { + if memo[m][n] != -1 { + return memo[m][n] + } + if obstacleGrid[m][n] == 1 { + return 0 + } + res := calcUniquePaths(obstacleGrid, m-1, n, memo) + calcUniquePaths(obstacleGrid, m, n-1, memo) + memo[m][n] = res + return res +} +*/ + +// dynamic programming +func uniquePathsWithObstacles(obstacleGrid [][]int) int { + m := len(obstacleGrid) + n := len(obstacleGrid[0]) + + memo := make([][]int, m) + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + memo[i] = append(memo[i], -1) + } + } + cur := 1 + for i := 0; i < m; i++ { + if obstacleGrid[i][0] == 1 { + cur = 0 + } + memo[i][0] = cur + } + + cur = 1 + for j := 0; j < n; j++ { + if obstacleGrid[0][j] == 1 { + cur = 0 + } + memo[0][j] = cur + } + for i := 1; i < m; i++ { + for j := 1; j < n; j++ { + if obstacleGrid[i][j] == 1 { + memo[i][j] = 0 + } else { + memo[i][j] = memo[i-1][j] + memo[i][j-1] + } + } + } + return memo[m-1][n-1] +} diff --git a/src/0063_unique_paths_2/unique_paths2_test.go b/src/0063_unique_paths_2/unique_paths2_test.go new file mode 100644 index 0000000..3de4356 --- /dev/null +++ b/src/0063_unique_paths_2/unique_paths2_test.go @@ -0,0 +1,33 @@ +package uniquepaths2 + +import "testing" + +func TestUniquePaths2(t *testing.T) { + testData := [][][]int{ + { + {0, 0, 0}, + {0, 1, 0}, + {0, 0, 0}, + }, + { + {0, 0, 0}, + {0, 1, 0}, + {0, 0, 0}, + {0, 1, 0}, + }, + { + {1}, + }, + { + {1, 0}, + }, + } + + expectedData := []int{2, 2, 0, 0} + + for index, data := range testData { + if res := uniquePathsWithObstacles(data); res != expectedData[index] { + t.Errorf("expected %d, got %d", expectedData[index], res) + } + } +} diff --git a/src/0064_minimum_path_sum/minimum_path_sum.go b/src/0064_minimum_path_sum/minimum_path_sum.go new file mode 100644 index 0000000..042cc78 --- /dev/null +++ b/src/0064_minimum_path_sum/minimum_path_sum.go @@ -0,0 +1,97 @@ +/* +64. Minimum Path Sum +source: https://leetcode.com/problems/minimum-path-sum/ + +Description +Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path. + Note: You can only move either down or right at any point in time. + +Example: + +Input: +[ + [1,3,1], + [1,5,1], + [4,2,1] +] +Output: 7 +Explanation: Because the path 1→3→1→1→1 minimizes the sum. +*/ + +package minimumpathsum + +// recursion dfs +/* +func minPathSum(grid [][]int) int { + if len(grid) == 0{ + return 0 + } + + MaxUint:= ^uint(0) + MaxInt := int(MaxUint >> 1) + + result := MaxInt + + dfs(0,0,0, grid, &result) + return result +} + +func dfs(x int, y int, sum int, grid [][]int, result *int) { + m := len(grid) + n := len(grid[0]) + + sum += grid[x][y] + + if x+1 < m && y+1 < n { + dfs(x+1, y, sum, grid, result) + dfs(x, y+1, sum, grid, result) + } + + if x +1 == m && y+1 < n { + dfs(x, y+1, sum, grid, result) + } + + if y+1 == n && x+1 < m { + dfs(x+1, y, sum, grid, result) + } + + + if x+1 == m && y+1 == n { + if sum < *result { + *result = sum + } + return + } +}*/ + +// dynamic programming +func minPathSum(grid [][]int) int { + if len(grid) == 0 { + return 0 + } + m := len(grid) + n := len(grid[0]) + + dp := make([][]int, m) + + dp[0] = append(dp[0], grid[0][0]) + + for i := 1; i < m; i++ { + dp[i] = append(dp[i], grid[i][0]+dp[i-1][0]) + } + + for i := 1; i < n; i++ { + dp[0] = append(dp[0], grid[0][i]+dp[0][i-1]) + } + + for i := 1; i < m; i++ { + for j := 1; j < n; j++ { + if dp[i-1][j] < dp[i][j-1] { + dp[i] = append(dp[i], grid[i][j]+dp[i-1][j]) + } else { + dp[i] = append(dp[i], grid[i][j]+dp[i][j-1]) + } + } + } + return dp[m-1][n-1] +} diff --git a/src/0064_minimum_path_sum/minimum_path_sum_test.go b/src/0064_minimum_path_sum/minimum_path_sum_test.go new file mode 100644 index 0000000..1cbb792 --- /dev/null +++ b/src/0064_minimum_path_sum/minimum_path_sum_test.go @@ -0,0 +1,42 @@ +package minimumpathsum + +import "testing" + +func TestMininumPathSum(t *testing.T) { + testData := [][][]int{ + { + {1, 3, 1}, + {1, 5, 1}, + {4, 2, 1}, + }, + { + {3, 8, 6, 0, 5, 9, 9, 6, 3, 4, 0, 5, 7, 3, 9, 3}, + {0, 9, 2, 5, 5, 4, 9, 1, 4, 6, 9, 5, 6, 7, 3, 2}, + {8, 2, 2, 3, 3, 3, 1, 6, 9, 1, 1, 6, 6, 2, 1, 9}, + {1, 3, 6, 9, 9, 5, 0, 3, 4, 9, 1, 0, 9, 6, 2, 7}, + {8, 6, 2, 2, 1, 3, 0, 0, 7, 2, 7, 5, 4, 8, 4, 8}, + {4, 1, 9, 5, 8, 9, 9, 2, 0, 2, 5, 1, 8, 7, 0, 9}, + {6, 2, 1, 7, 8, 1, 8, 5, 5, 7, 0, 2, 5, 7, 2, 1}, + {8, 1, 7, 6, 2, 8, 1, 2, 2, 6, 4, 0, 5, 4, 1, 3}, + {9, 2, 1, 7, 6, 1, 4, 3, 8, 6, 5, 5, 3, 9, 7, 3}, + {0, 6, 0, 2, 4, 3, 7, 6, 1, 3, 8, 6, 9, 0, 0, 8}, + {4, 3, 7, 2, 4, 3, 6, 4, 0, 3, 9, 5, 3, 6, 9, 3}, + {2, 1, 8, 8, 4, 5, 6, 5, 8, 7, 3, 7, 7, 5, 8, 3}, + {0, 7, 6, 6, 1, 2, 0, 3, 5, 0, 8, 0, 8, 7, 4, 3}, + {0, 4, 3, 4, 9, 0, 1, 9, 7, 7, 8, 6, 4, 6, 9, 5}, + {6, 5, 1, 9, 9, 2, 2, 7, 4, 2, 7, 2, 2, 3, 7, 2}, + {7, 1, 9, 6, 1, 2, 7, 0, 9, 6, 6, 4, 4, 5, 1, 0}, + {3, 4, 9, 2, 8, 3, 1, 2, 6, 9, 7, 0, 2, 4, 2, 0}, + {5, 1, 8, 8, 4, 6, 8, 5, 2, 4, 1, 6, 2, 2, 9, 7}, + }, + {}, + } + + expectedData := []int{7, 83, 0} + + for index, data := range testData { + if mininumPathSum := minPathSum(data); expectedData[index] != mininumPathSum { + t.Errorf("expected %d, got %d", expectedData[index], mininumPathSum) + } + } +} diff --git a/src/0067_add_binary/README.md b/src/0067_add_binary/README.md new file mode 100644 index 0000000..79ec2ab --- /dev/null +++ b/src/0067_add_binary/README.md @@ -0,0 +1,26 @@ +# [add Binary](https://leetcode.com/problems/add-binary/) + +## Description + +> Given two binary strings, return their sum (also a binary string). +> +> The input strings are both non-empty and contains only characters 1 or 0. + +Example 1: + +``` +Input: a = "11", b = "1" +Output: "100" +``` + +Example 2: + +``` +Input: a = "1010", b = "1011" +Output: "10101" +``` + +## Solution + +implement by python +> bin(int(a, 2) + int(b, 2))[2:] diff --git a/src/0070_climbing_stairs/climbing_stairs.go b/src/0070_climbing_stairs/climbing_stairs.go new file mode 100644 index 0000000..e4b38bb --- /dev/null +++ b/src/0070_climbing_stairs/climbing_stairs.go @@ -0,0 +1,80 @@ +/* +70. Climbing Stairs + +source:https://leetcode.com/problems/climbing-stairs/ + +You are climbing a stair case. It takes n steps to reach to the top. + +Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top? + +Note: Given n will be a positive integer. + +Example 1: + +Input: 2 +Output: 2 +Explanation: There are two ways to climb to the top. +1. 1 step + 1 step +2. 2 steps +Example 2: + +Input: 3 +Output: 3 +Explanation: There are three ways to climb to the top. +1. 1 step + 1 step + 1 step +2. 1 step + 2 steps +3. 2 steps + 1 step +*/ + +package climbingstairs + +// recursion +/* +func climbStairs(n int) int { + // if n == 1 { + // return 1 + // } + // if n == 2 { + // return 2 + // } + // + + if n == 1 || n == 0 { + return 1 + } + + return climbStairs(n-1) + climbStairs(n-2) +} +*/ + +// memory search +/* +func climbStairs(n int) int { + var memo []int + for i := 0; i <= n; i++ { + memo = append(memo, -1) + } + return calcWays(n, memo) +} + +func calcWays(n int, memo []int) int { + if n == 0 || n == 1 { + return 1 + } + + if memo[n] == -1 { + memo[n] = calcWays(n-1, memo) + calcWays(n-2, memo) + } + + return memo[n] +} +*/ + +// dynamic programming +func climbStairs(n int) int { + var memo = []int{1, 1} + for i := 2; i <= n; i++ { + memo = append(memo, memo[i-1]+memo[i-2]) + } + return memo[n] +} diff --git a/src/0070_climbing_stairs/climbing_stairs_test.go b/src/0070_climbing_stairs/climbing_stairs_test.go new file mode 100644 index 0000000..530d996 --- /dev/null +++ b/src/0070_climbing_stairs/climbing_stairs_test.go @@ -0,0 +1,14 @@ +package climbingstairs + +import "testing" + +func TestClimbStairs(t *testing.T) { + testDatas := []int{0, 1, 2, 3, 34} + expected := []int{1, 1, 2, 3, 9227465} + + for i, data := range testDatas { + if steps := climbStairs(data); steps != expected[i] { + t.Errorf("expected %d, got %d", expected[i], steps) + } + } +} diff --git a/src/0076_minimum_window_substring/minimum_window_substring.go b/src/0076_minimum_window_substring/minimum_window_substring.go new file mode 100644 index 0000000..ac17090 --- /dev/null +++ b/src/0076_minimum_window_substring/minimum_window_substring.go @@ -0,0 +1,62 @@ +/* +76. Minimum Window Substring +https://leetcode.com/problems/minimum-window-substring/ + +Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n). + +Example: + Input: S = "ADOBECODEBANC", T = "ABC" + Output: "BANC" + +Note: + 1. If there is no such window in S that covers all characters in T, return the empty string "". + 2. If there is such window, you are guaranteed that there will always be only one unique minimum window in S. +*/ + +package minimumwindowsubstring + +import "leetcode/utils" + +/* +使用滑动窗口解决这一问题,使用map或者slice统计T字符串中的字母的个数,之后,开始遍历S字符串,对于S中遍历到 +的每一个字母,都在map或者slice中的对应个数减一,如果减一后仍然大于等于0,说明当前遍历到的字母是T中的字母, +使用计数器count,使其加一,当count和T串字母个数相等时,说明此时的窗口已经包含了T串中的所有字母,此时记录 +一下字串和字串长度, +然后开始收缩左边界,由于我们遍历的时候,对应值减了1,所以此时去除字母的时候,就要把减去的1加回来, +此时如果加1后的值大于0了,说明此时我们少了一个T中的字母,那么count值就要减1了,然后移动左边界left。 +*/ + +// sliding window +// Time complexity: O(n) +// Space complexity: O(128) = O(1) +func minWindow(s string, t string) string { + var ( + res string + letterCount = make([]int, 128) + left int + count int + minLen = utils.MaxInt + ) + + for i := 0; i < len(t); i++ { + letterCount[t[i]]++ + } + + for i := 0; i < len(s); i++ { + if letterCount[s[i]]--; letterCount[s[i]] >= 0 { + count++ + } + + for count == len(t) { + if minLen > i-left+1 { + minLen = i - left + 1 + res = s[left : minLen+left] + } + if letterCount[s[left]]++; letterCount[s[left]] > 0 { + count-- + } + left++ + } + } + return res +} diff --git a/src/0076_minimum_window_substring/minimum_window_substring_test.go b/src/0076_minimum_window_substring/minimum_window_substring_test.go new file mode 100644 index 0000000..1af6da7 --- /dev/null +++ b/src/0076_minimum_window_substring/minimum_window_substring_test.go @@ -0,0 +1,14 @@ +package minimumwindowsubstring + +import "testing" + +func TestMinWindow(t *testing.T) { + s := "ADOBECODEBANC" + l := "ABC" + expected := "BANC" + + if res := minWindow(s, l); res != expected { + t.Errorf("expected %s, got %s", expected, res) + } + +} diff --git a/src/0094_binary_tree_inorder_traversal/binary_tree_inorder_traversal.go b/src/0094_binary_tree_inorder_traversal/binary_tree_inorder_traversal.go new file mode 100644 index 0000000..a0b9a40 --- /dev/null +++ b/src/0094_binary_tree_inorder_traversal/binary_tree_inorder_traversal.go @@ -0,0 +1,42 @@ +/* +94. Binary Tree Inorder Traversal +source: https://leetcode.com/problems/binary-tree-inorder-traversal/ + +Given a binary tree, return the inorder traversal of its nodes' values. + +Example: + +Input: [1,null,2,3] + 1 + \ + 2 + / + 3 + +Output: [1,3,2] +Follow up: Recursive solution is trivial, could you do it iteratively? +*/ + +package binarytreeinordertraversal + +// TreeNode binary tree node. +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func inorderTraversal(root *TreeNode) []int { + res := make([]int, 0, 1) + inorderTraversalHelp(root, &res) + return res +} + +func inorderTraversalHelp(root *TreeNode, res *[]int) { + if root == nil { + return + } + inorderTraversalHelp(root.Left, res) + *res = append(*res, root.Val) + inorderTraversalHelp(root.Right, res) +} diff --git a/src/0094_binary_tree_inorder_traversal/binary_tree_inorder_traversal_test.go b/src/0094_binary_tree_inorder_traversal/binary_tree_inorder_traversal_test.go new file mode 100644 index 0000000..a225f6b --- /dev/null +++ b/src/0094_binary_tree_inorder_traversal/binary_tree_inorder_traversal_test.go @@ -0,0 +1,36 @@ +package binarytreeinordertraversal + +import ( + "reflect" + "testing" +) + +func createBinaryTree(nums []int) *TreeNode { + return performCreate(nums, 0) +} + +func performCreate(nums []int, index int) *TreeNode { + if index >= len(nums) { + return nil + } + + tree := TreeNode{Val: nums[index]} + tree.Left = performCreate(nums, 2*index+1) + tree.Right = performCreate(nums, 2*index+2) + return &tree +} + +func TestInorderTraversal(t *testing.T) { + testData := [][]int{ + {1, 2, 3}, + } + expectedData := [][]int{ + {2, 1, 3}, + } + + for index, data := range testData { + if res := inorderTraversal(createBinaryTree(data)); !reflect.DeepEqual(res, expectedData[index]) { + t.Errorf("expected %v, got %v", expectedData[index], res) + } + } +} diff --git a/src/0100_same_tree/same_tree.go b/src/0100_same_tree/same_tree.go new file mode 100644 index 0000000..cf50a89 --- /dev/null +++ b/src/0100_same_tree/same_tree.go @@ -0,0 +1,31 @@ +/* +100. Same Tree +https://leetcode.com/problems/same-tree/ + +Given two binary trees, write a function to check if they are the same or not. + +Two binary trees are considered the same if they are structurally identical and the nodes have the same value. + +*/ + +package sametree + +// TreeNode binary tree node. +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func isSameTree(p *TreeNode, q *TreeNode) bool { + if p == nil { + return q == nil + } + if q == nil { + return p == nil + } + if p.Val == q.Val { + return isSameTree(p.Left, q.Left) && isSameTree(p.Right, q.Right) + } + return false +} diff --git a/src/0100_same_tree/same_tree_test.go b/src/0100_same_tree/same_tree_test.go new file mode 100644 index 0000000..971a44c --- /dev/null +++ b/src/0100_same_tree/same_tree_test.go @@ -0,0 +1,39 @@ +package sametree + +import "testing" + +type arg struct { + p []int + q []int +} + +func createBinaryTree(nums []int) *TreeNode { + return performCreate(nums, 0) +} + +func performCreate(nums []int, index int) *TreeNode { + if index >= len(nums) { + return nil + } + + tree := TreeNode{Val: nums[index]} + tree.Left = performCreate(nums, 2*index+1) + tree.Right = performCreate(nums, 2*index+2) + return &tree +} + +func TestSameTree(t *testing.T) { + testData := []arg{ + arg{p: []int{1, 2, 3}, q: []int{1, 2, 3}}, + arg{p: []int{1, 2, 3}, q: []int{1, 2}}, + arg{p: []int{1, 2, 3}, q: []int{1, 2, 4}}, + } + + expectedData := []bool{true, false, false} + + for index, data := range testData { + if res := isSameTree(createBinaryTree(data.p), createBinaryTree(data.q)); res != expectedData[index] { + t.Errorf("expected %t, got %t", expectedData[index], res) + } + } +} diff --git a/src/0101_symmetric_tree/symmetric_tree.go b/src/0101_symmetric_tree/symmetric_tree.go new file mode 100644 index 0000000..fb266fb --- /dev/null +++ b/src/0101_symmetric_tree/symmetric_tree.go @@ -0,0 +1,33 @@ +/* +101. Symmetric Tree +https://leetcode.com/problems/symmetric-tree/ + +Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). +*/ + +package symmetrictree + +// TreeNode binary tree node. +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func isSymmetric(root *TreeNode) bool { + if root == nil { + return true + } + return symmetric(root.Left, root.Right) +} + +func symmetric(left *TreeNode, right *TreeNode) bool { + if left == nil && right == nil { + return true + } + + if left == nil || right == nil { + return false + } + return left.Val == right.Val && symmetric(left.Left, right.Right) && symmetric(left.Right, right.Left) +} diff --git a/src/0101_symmetric_tree/symmetric_tree_test.go b/src/0101_symmetric_tree/symmetric_tree_test.go new file mode 100644 index 0000000..9550366 --- /dev/null +++ b/src/0101_symmetric_tree/symmetric_tree_test.go @@ -0,0 +1,35 @@ +package symmetrictree + +import ( + "testing" +) + +func createBinaryTree(nums []int) *TreeNode { + return performCreate(nums, 0) +} + +func performCreate(nums []int, index int) *TreeNode { + if index >= len(nums) { + return nil + } + + tree := TreeNode{Val: nums[index]} + tree.Left = performCreate(nums, 2*index+1) + tree.Right = performCreate(nums, 2*index+2) + return &tree +} + +func TestIsSymmetric(t *testing.T) { + testData := [][]int{ + {1, 2, 2, 3, 4, 4, 3}, + {1, 2, 2, 3, 3}, + {}, + } + expectedData := []bool{true, false, true} + + for index, data := range testData { + if res := isSymmetric(createBinaryTree(data)); res != expectedData[index] { + t.Errorf("expected %t, got %t", expectedData[index], res) + } + } +} diff --git a/src/0107_binary_tree_level_order_traversal_2/binary_tree_level_order_traversal2.go b/src/0107_binary_tree_level_order_traversal_2/binary_tree_level_order_traversal2.go new file mode 100644 index 0000000..d17a03c --- /dev/null +++ b/src/0107_binary_tree_level_order_traversal_2/binary_tree_level_order_traversal2.go @@ -0,0 +1,39 @@ +/* +107. Binary Tree Level Order Traversal II +https://leetcode.com/problems/binary-tree-level-order-traversal-ii/ + +Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root). +*/ + +package binarytreelevelordertraversal2 + +// TreeNode binary tree node. +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func levelOrderBottom(root *TreeNode) [][]int { + var record [][]int + traversal(root, 0, &record) + var reversed [][]int + for i := len(record) - 1; i >= 0; i-- { + reversed = append(reversed, record[i]) + } + return reversed +} + +func traversal(root *TreeNode, index int, record *[][]int) { + if root == nil { + return + } + if len(*record) == index { + *record = append(*record, make([]int, 0)) + } + (*record)[index] = append((*record)[index], root.Val) + traversal(root.Left, index+1, record) + traversal(root.Right, index+1, record) + // (*record)[len(*record)-1-index] = append((*record)[len(*record)-1-index], root.Val) + // 这个方法用java可以实现,go不行,猜测可能跟java的递归实现有关。 +} diff --git a/src/0107_binary_tree_level_order_traversal_2/binary_tree_level_order_traversal2_test.go b/src/0107_binary_tree_level_order_traversal_2/binary_tree_level_order_traversal2_test.go new file mode 100644 index 0000000..e1bb983 --- /dev/null +++ b/src/0107_binary_tree_level_order_traversal_2/binary_tree_level_order_traversal2_test.go @@ -0,0 +1,40 @@ +package binarytreelevelordertraversal2 + +import ( + "reflect" + "testing" +) + +func createBinaryTree(nums []int) *TreeNode { + return performCreate(nums, 0) +} + +func performCreate(nums []int, index int) *TreeNode { + if index >= len(nums) { + return nil + } + + tree := TreeNode{Val: nums[index]} + tree.Left = performCreate(nums, 2*index+1) + tree.Right = performCreate(nums, 2*index+2) + return &tree +} + +func TestBinaryTreeLevelOrderTraversal2(t *testing.T) { + testData := [][]int{ + {3, 9, 20, 15, 17}, + } + expectedData := [][][]int{ + { + {15, 17}, + {9, 20}, + {3}, + }, + } + + for index, data := range testData { + if res := levelOrderBottom(createBinaryTree(data)); !reflect.DeepEqual(res, expectedData[index]) { + t.Errorf("expected %v, got %v", expectedData[index], res) + } + } +} diff --git a/src/0111_minimum_depth_of_binary_tree/minimum_depth_of_binary_tree.go b/src/0111_minimum_depth_of_binary_tree/minimum_depth_of_binary_tree.go new file mode 100644 index 0000000..fd10379 --- /dev/null +++ b/src/0111_minimum_depth_of_binary_tree/minimum_depth_of_binary_tree.go @@ -0,0 +1,35 @@ +/* +111. Minimum Depth of Binary Tree +https://leetcode.com/problems/minimum-depth-of-binary-tree/ + +Given a binary tree, find its minimum depth. + +The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node. + +Note: A leaf is a node with no children. + +*/ + +package minimumdepthofbinarytree + +import "leetcode/utils" + +// TreeNode binary tree node. +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func minDepth(root *TreeNode) int { + if root == nil { + return 0 + } + left := minDepth(root.Left) + right := minDepth(root.Right) + + if left == 0 || right == 0 { + return utils.CalcMaxInt(left, right) + 1 + } + return utils.CalcMinInt(left, right) + 1 +} diff --git a/src/0111_minimum_depth_of_binary_tree/minimum_depth_of_binary_tree_test.go b/src/0111_minimum_depth_of_binary_tree/minimum_depth_of_binary_tree_test.go new file mode 100644 index 0000000..01a0cac --- /dev/null +++ b/src/0111_minimum_depth_of_binary_tree/minimum_depth_of_binary_tree_test.go @@ -0,0 +1,31 @@ +package minimumdepthofbinarytree + +import "testing" + +func createBinaryTree(nums []int) *TreeNode { + return performCreate(nums, 0) +} + +func performCreate(nums []int, index int) *TreeNode { + if index >= len(nums) { + return nil + } + + tree := TreeNode{Val: nums[index]} + tree.Left = performCreate(nums, 2*index+1) + tree.Right = performCreate(nums, 2*index+2) + return &tree +} +func TestMinDepth(t *testing.T) { + testData := [][]int{ + {3, 9, 20, 15, 7}, + } + + expectedData := []int{2} + + for index, data := range testData { + if res := minDepth(createBinaryTree(data)); res != expectedData[index] { + t.Errorf("expected %d, got %d", expectedData[index], res) + } + } +} diff --git a/src/0112_path_sum/path_sum.go b/src/0112_path_sum/path_sum.go new file mode 100644 index 0000000..b410d61 --- /dev/null +++ b/src/0112_path_sum/path_sum.go @@ -0,0 +1,28 @@ +/* +112. Path Sum +https://leetcode.com/problems/path-sum/ + +Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum. + +Note: A leaf is a node with no children. +*/ + +package pathsum + +// TreeNode binary tree node. +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func hasPathSum(root *TreeNode, sum int) bool { + if root == nil { + return false + } + + if root.Left == nil && root.Right == nil { + return root.Val == sum + } + return hasPathSum(root.Left, sum-root.Val) || hasPathSum(root.Right, sum-root.Val) +} diff --git a/src/0112_path_sum/path_sum_test.go b/src/0112_path_sum/path_sum_test.go new file mode 100644 index 0000000..48c4b01 --- /dev/null +++ b/src/0112_path_sum/path_sum_test.go @@ -0,0 +1,46 @@ +package pathsum + +import ( + "os" + "testing" +) + +func createBinaryTree(nums []interface{}) *TreeNode { + return performCreate(nums, 0) +} + +func performCreate(nums []interface{}, index int) *TreeNode { + if !(index < len(nums)) || nums[index] == nil { + return nil + } + + tree := TreeNode{} + if num, ok := nums[index].(int); ok { // type assertion + tree.Val = num + } + tree.Left = performCreate(nums, 2*index+1) + tree.Right = performCreate(nums, 2*index+2) + return &tree +} + +type arg struct { + nums []interface{} + sum int +} + +func TestHasPathSum(t *testing.T) { + testData := []arg{ + arg{nums: []interface{}{5, 4, 8, 11, nil, 13, 4, 7, 2, nil, nil, nil, 1}, sum: 22}, + arg{nums: []interface{}{}, sum: 0}, + } + expectedData := []bool{true, false} + for index, data := range testData { + if res := hasPathSum(createBinaryTree(data.nums), data.sum); res != expectedData[index] { + t.Errorf("expected %t, got %t", expectedData[index], res) + } + } +} + +func TestMain(m *testing.M) { + os.Exit(m.Run()) +} diff --git a/src/0120_triangle/triangle.go b/src/0120_triangle/triangle.go new file mode 100644 index 0000000..af590fa --- /dev/null +++ b/src/0120_triangle/triangle.go @@ -0,0 +1,70 @@ +/* +120. Triangle +https://leetcode.com/problems/triangle/ + +Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below. + +*/ + +package triangle + +import "leetcode/utils" + +// dfs +/* +func minimumTotal(triangle [][]int) int { + if len(triangle) == 0 { + return 0 + } + result := utils.MaxInt + dfs(0, 0, 0, triangle, &result) + return result +} + +func dfs(x int, y int, sum int, triangle [][]int, result *int) { + if len(triangle) == x { + if sum < *result { + *result = sum + } + return + } + sum += triangle[x][y] + + dfs(x+1, y, sum, triangle, result) + dfs(x+1, y+1, sum, triangle, result) +} +*/ + +// dynamic programming +func minimumTotal(triangle [][]int) int { + m := len(triangle) + if m == 0 { + return 0 + } + + dp := make([][]int, m) + + dp[0] = append(dp[0], triangle[0][0]) + + for i := 1; i < m; i++ { + for j, num := range triangle[i] { + if j >= len(dp[i-1]) { + dp[i] = append(dp[i], num+dp[i-1][j-1]) + } else { + if j-1 >= 0 && dp[i-1][j-1] < dp[i-1][j] { + dp[i] = append(dp[i], num+dp[i-1][j-1]) + } else { + dp[i] = append(dp[i], num+dp[i-1][j]) + } + } + } + } + + var mininum = utils.MaxInt + for _, num := range dp[m-1] { + if num < mininum { + mininum = num + } + } + return mininum +} diff --git a/src/0120_triangle/triangle_test.go b/src/0120_triangle/triangle_test.go new file mode 100644 index 0000000..893ed1c --- /dev/null +++ b/src/0120_triangle/triangle_test.go @@ -0,0 +1,21 @@ +package triangle + +import ( + "testing" +) + +func TestTriangle(t *testing.T) { + testData := [][][]int{ + [][]int{[]int{2}, []int{3, 4}, []int{6, 5, 7}, []int{4, 1, 8, 3}}, + [][]int{}, + [][]int{[]int{-1}, []int{2, 3}, []int{1, -1, -3}}, + } + + expectedData := []int{11, 0, -1} + + for index, data := range testData { + if mininum := minimumTotal(data); mininum != expectedData[index] { + t.Errorf("expected %d, got %d", expectedData[index], mininum) + } + } +} diff --git a/src/0167_two_sum2/two_sum2.go b/src/0167_two_sum2/two_sum2.go new file mode 100644 index 0000000..1029310 --- /dev/null +++ b/src/0167_two_sum2/two_sum2.go @@ -0,0 +1,39 @@ +/* +167. Two Sum II - Input array is sorted +https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/ + +Given an array of integers that is already sorted in ascending order, find two numbers such that they add up to a specific target number. + +The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. + +Note: + Your returned answers (both index1 and index2) are not zero-based. + You may assume that each input would have exactly one solution and you may not use the same element twice. + + Example: + +Input: numbers = [2,7,11,15], target = 9 +Output: [1,2] +Explanation: The sum of 2 and 7 is 9. Therefore index1 = 1, index2 = 2. +*/ + +package twosum2 + +func twoSum2(numbers []int, target int) []int { + n := len(numbers) + var ( + l = 0 + r = n - 1 + ) + + for l < r { + if numbers[l]+numbers[r] == target { + return []int{l + 1, r + 1} + } else if numbers[l]+numbers[r] < target { + l++ + } else { + r-- + } + } + panic("The input has no solution.") +} diff --git a/src/0167_two_sum2/two_sum2_test.go b/src/0167_two_sum2/two_sum2_test.go new file mode 100644 index 0000000..2de0c60 --- /dev/null +++ b/src/0167_two_sum2/two_sum2_test.go @@ -0,0 +1,38 @@ +package twosum2 + +import ( + "reflect" + "testing" +) + +type arg struct { + numbers []int + target int +} + +func TestTwoSum2(t *testing.T) { + testData := []arg{ + arg{ + numbers: []int{2, 7, 11, 15}, + target: 9, + }, + } + + expectedData := [][]int{ + {1, 2}, + } + + for index, data := range testData { + if res := twoSum2(data.numbers, data.target); !reflect.DeepEqual(res, expectedData[index]) { + t.Errorf("expected %v, got %v", expectedData[index], res) + } + } + + defer func() { + if err := recover(); err == nil { + t.Errorf("there should throw a panic") + } + }() + + twoSum2([]int{2, 7, 11, 15}, 90) +} diff --git a/src/0198_house_robber/house_robber.go b/src/0198_house_robber/house_robber.go new file mode 100644 index 0000000..b6f1e07 --- /dev/null +++ b/src/0198_house_robber/house_robber.go @@ -0,0 +1,100 @@ +/* +198. House Robber +https://leetcode.com/problems/house-robber/ + +You are a professional robber planning to rob houses along a street. Each house has a certain amount + of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses + have security system connected and it will automatically contact the police if two adjacent houses were + broken into on the same night. + +Given a list of non-negative integers representing the amount of money of each house, determine the +maximum amount of money you can rob tonight without alerting the police. + +Example 1: + +Input: [1,2,3,1] +Output: 4 +Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3). + Total amount you can rob = 1 + 3 = 4. +Example 2: + +Input: [2,7,9,3,1] +Output: 12 +Explanation: Rob house 1 (money = 2), rob house 3 (money = 9) and rob house 5 (money = 1). + Total amount you can rob = 2 + 9 + 1 = 12. +*/ + +package houserobber + +import "leetcode/utils" + +/* +func rob(nums []int) int { + return tryRob(nums, 0) +} + +func tryRob(nums []int, index int) int { + if index >= len(nums) { + return 0 + } + + var res int + for i := index; i < len(nums); i++ { + res, _ = utils.CalcMaxInt(res, nums[i]+tryRob(nums, i+2)) + } + return res +} +*/ + +// memory search +/* +func rob(nums []int) int { + memo := make([]int, len(nums)) + for i := 0; i < len(nums); i++ { + memo[i] = -1 + } + return tryRob(nums, 0, memo) +} + +func tryRob(nums []int, index int, memo []int) int { + if index >= len(nums) { + return 0 + } + + if memo[index] != -1 { + return memo[index] + } + + var res int + for i := index; i < len(nums); i++ { + res, _ = utils.CalcMaxInt(res, nums[i]+tryRob(nums, i+2, memo)) + } + memo[index] = res + return res +}*/ + +// dynamic programming +func rob(nums []int) int { + n := len(nums) + if n == 0 { + return 0 + } + + memo := make([]int, n) + + for i := 0; i < n; i++ { + memo[i] = -1 + } + memo[n-1] = nums[n-1] + + for i := n - 2; i >= 0; i-- { + for j := i; j < n; j++ { + if j+2 < n { + memo[i] = utils.CalcMaxInt(memo[i], nums[j]+memo[j+2]) + } else { + memo[i] = utils.CalcMaxInt(memo[i], nums[j]) + } + } + } + return memo[0] +} diff --git a/src/0198_house_robber/house_robber_test.go b/src/0198_house_robber/house_robber_test.go new file mode 100644 index 0000000..38131af --- /dev/null +++ b/src/0198_house_robber/house_robber_test.go @@ -0,0 +1,19 @@ +package houserobber + +import "testing" + +func TestHouseRobber(t *testing.T) { + testData := [][]int{ + {1, 2, 3, 1}, + {9, 1, 293, 5986, 81, 384}, + {1, 2}, + {}, + } + expectedData := []int{4, 6379, 2, 0} + + for index, data := range testData { + if res := rob(data); res != expectedData[index] { + t.Errorf("expected %d, got %d", expectedData[index], res) + } + } +} diff --git a/src/0209_minimum_size_subarray_sum/minimum_size_subarray_sum.go b/src/0209_minimum_size_subarray_sum/minimum_size_subarray_sum.go new file mode 100644 index 0000000..a6632e7 --- /dev/null +++ b/src/0209_minimum_size_subarray_sum/minimum_size_subarray_sum.go @@ -0,0 +1,43 @@ +/* +209. Minimum Size Subarray Sum +https://leetcode.com/problems/minimum-size-subarray-sum/ + +Given an array of n positive integers and a positive integer s, find the minimal length of a contiguous subarray of which the sum ≥ s. If there isn't one, return 0 instead. + +Example: + +Input: s = 7, nums = [2,3,1,2,4,3] +Output: 2 +Explanation: the subarray [4,3] has the minimal length under the problem constraint. + +Follow up: +If you have figured out the O(n) solution, try coding another solution of which the time complexity is O(n log n). +*/ + +package minimumsizesubarraysum + +func minSubArrayLen(s int, nums []int) int { + var ( + l = 0 + r = -1 + res = len(nums) + 1 + sum = 0 + ) + + for l < len(nums) { + if sum < s && r+1 < len(nums) { + r++ + sum += nums[r] + } else { + sum -= nums[l] + l++ + } + if sum >= s && res > r-l+1 { + res = r - l + 1 + } + } + if res == len(nums)+1 { + return 0 + } + return res +} diff --git a/src/0209_minimum_size_subarray_sum/minimum_size_subarray_sum_test.go b/src/0209_minimum_size_subarray_sum/minimum_size_subarray_sum_test.go new file mode 100644 index 0000000..c4d12b1 --- /dev/null +++ b/src/0209_minimum_size_subarray_sum/minimum_size_subarray_sum_test.go @@ -0,0 +1,32 @@ +package minimumsizesubarraysum + +import "testing" + +func TestMinSubArrayLen(t *testing.T) { + type arg struct { + s int + nums []int + } + testData := []arg{ + arg{ + s: 7, + nums: []int{2, 3, 1, 2, 4, 3}, + }, + arg{ + s: 7, + nums: []int{7, 4, 3, 2}, + }, + arg{ + s: 66, + nums: []int{7, 4, 3, 2}, + }, + } + + expectedData := []int{2, 1, 0} + + for index, data := range testData { + if res := minSubArrayLen(data.s, data.nums); res != expectedData[index] { + t.Errorf("expected %d, got %d", expectedData[index], res) + } + } +} diff --git a/src/0226_invert_binary_tree/invert_binary_tree.go b/src/0226_invert_binary_tree/invert_binary_tree.go new file mode 100644 index 0000000..416f76e --- /dev/null +++ b/src/0226_invert_binary_tree/invert_binary_tree.go @@ -0,0 +1,28 @@ +/* +226. Invert Binary Tree +https://leetcode.com/problems/invert-binary-tree/ + +Invert a binary tree. +*/ + +package invertbinarytree + +// TreeNode binary tree node +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +// Recursion +// Time complexity: O(n), where n is the node's number of the tree. +// Space complexity: O(h), where h is the height of the tree. +func invertTree(root *TreeNode) *TreeNode { + if root == nil { + return nil + } + root.Right, root.Left = root.Left, root.Right + invertTree(root.Left) + invertTree(root.Right) + return root +} diff --git a/src/0226_invert_binary_tree/invert_binary_tree_test.go b/src/0226_invert_binary_tree/invert_binary_tree_test.go new file mode 100644 index 0000000..a84f72d --- /dev/null +++ b/src/0226_invert_binary_tree/invert_binary_tree_test.go @@ -0,0 +1,59 @@ +package invertbinarytree + +import ( + "reflect" + "testing" +) + +func createBinaryTree(nums []interface{}) *TreeNode { + return performCreate(nums, 0) +} + +func performCreate(nums []interface{}, index int) *TreeNode { + if !(index < len(nums)) || nums[index] == nil { + return nil + } + + tree := TreeNode{} + if num, ok := nums[index].(int); ok { // type assertion + tree.Val = num + } + tree.Left = performCreate(nums, 2*index+1) + tree.Right = performCreate(nums, 2*index+2) + return &tree +} + +func levelOrderTraversal(root *TreeNode) []interface{} { + res := make([]interface{}, 0) + queue := make([]*TreeNode, 0) + queue = append(queue, root) + for len(queue) > 0 { + node := queue[0] + queue = queue[1:] + res = append(res, node.Val) + if node.Left != nil { + queue = append(queue, node.Left) + } + if node.Right != nil { + queue = append(queue, node.Right) + } + } + return res +} + +func TestInvertTree(t *testing.T) { + testData := [][]interface{}{ + {4, 2, 7, 1, 3, 6, 9}, + } + + expectedData := [][]interface{}{ + []interface{}{4, 7, 2, 9, 6, 3, 1}, + } + + for index, data := range testData { + tree := createBinaryTree(data) + if res := levelOrderTraversal(invertTree(tree)); !reflect.DeepEqual(res, expectedData[index]) { + t.Errorf("expected %v, got %v", expectedData[index], res) + } + } +} diff --git a/src/0283_move_zeroes/move_zeroes.go b/src/0283_move_zeroes/move_zeroes.go new file mode 100644 index 0000000..c80ca4d --- /dev/null +++ b/src/0283_move_zeroes/move_zeroes.go @@ -0,0 +1,22 @@ +/* +283. Move Zeroes +https://leetcode.com/problems/move-zeroes/ + +Given an array nums, write a function to move all 0's to the end of it while maintaining the relative order of the non-zero elements. +*/ + +package movezeroes + +// Time complexity: O(n) +// Space complexity: O(1) +func moveZeroes(nums []int) { + var k int + for i := range nums { + if nums[i] != 0 { + if k != i { + nums[i], nums[k] = nums[k], nums[i] + } + k++ + } + } +} diff --git a/src/0283_move_zeroes/move_zeroes2.go b/src/0283_move_zeroes/move_zeroes2.go new file mode 100644 index 0000000..36ace90 --- /dev/null +++ b/src/0283_move_zeroes/move_zeroes2.go @@ -0,0 +1,26 @@ +/* +283. Move Zeroes +https://leetcode.com/problems/move-zeroes/ + +Given an array nums, write a function to move all 0's to the end of it while maintaining the relative order of the non-zero elements. +*/ + +package movezeroes + +// Time complexity: O(n) +// Space complexity: O(1) +func moveZeroes2(nums []int) { + var k int + for i := range nums { + if nums[i] != 0 { + if k != i { + nums[k] = nums[i] + } + k++ + } + } + + for i := k; i < len(nums); i++ { + nums[i] = 0 + } +} diff --git a/src/0283_move_zeroes/move_zeroes2_test.go b/src/0283_move_zeroes/move_zeroes2_test.go new file mode 100644 index 0000000..8a3d8cc --- /dev/null +++ b/src/0283_move_zeroes/move_zeroes2_test.go @@ -0,0 +1,22 @@ +package movezeroes + +import ( + "reflect" + "testing" +) + +func TestMoveZeroes2(t *testing.T) { + testData := [][]int{ + {0, 1, 0, 3, 12}, + } + + expectedData := [][]int{ + {1, 3, 12, 0, 0}, + } + + for index, data := range testData { + if moveZeroes2(data); !reflect.DeepEqual(data, expectedData[index]) { + t.Errorf("expected %v, got %v", expectedData[index], data) + } + } +} diff --git a/src/0283_move_zeroes/move_zeroes_test.go b/src/0283_move_zeroes/move_zeroes_test.go new file mode 100644 index 0000000..780a94b --- /dev/null +++ b/src/0283_move_zeroes/move_zeroes_test.go @@ -0,0 +1,22 @@ +package movezeroes + +import ( + "reflect" + "testing" +) + +func TestMoveZeroes(t *testing.T) { + testData := [][]int{ + {0, 1, 0, 3, 12}, + } + + expectedData := [][]int{ + {1, 3, 12, 0, 0}, + } + + for index, data := range testData { + if moveZeroes(data); !reflect.DeepEqual(data, expectedData[index]) { + t.Errorf("expected %v, got %v", expectedData[index], data) + } + } +} diff --git a/src/0300_longest_increasing_subsequence/lis.go b/src/0300_longest_increasing_subsequence/lis.go new file mode 100644 index 0000000..eb3a58a --- /dev/null +++ b/src/0300_longest_increasing_subsequence/lis.go @@ -0,0 +1,47 @@ +/* +300. Longest Increasing Subsequence +https://leetcode.com/problems/longest-increasing-subsequence/ + +Given an unsorted array of integers, find the length of longest increasing subsequence. + +Example: + +Input: [10,9,2,5,3,7,101,18] +Output: 4 +Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4. +Note: + +There may be more than one LIS combination, it is only necessary for you to return the length. +Your algorithm should run in O(n2) complexity. + +Follow up: + Could you improve it to O(n log n) time complexity? +*/ + +package lis + +import "leetcode/utils" + +// Dynamic Programming +// TIme complexity: O(n^2) +// Space Complexity: O(n) +func lengthOfLIS(nums []int) int { + n := len(nums) + if n == 0 { + return 0 + } + + memo := make([]int, n) + for i := 0; i < n; i++ { + memo[i] = 1 + } + + for i := 1; i < n; i++ { + for j := 0; j < i; j++ { + if nums[j] < nums[i] { + memo[i] = utils.CalcMaxInt(memo[i], 1+memo[j]) + } + } + } + return utils.CalcMaxInt(memo...) +} diff --git a/src/0300_longest_increasing_subsequence/lis_test.go b/src/0300_longest_increasing_subsequence/lis_test.go new file mode 100644 index 0000000..3114c41 --- /dev/null +++ b/src/0300_longest_increasing_subsequence/lis_test.go @@ -0,0 +1,24 @@ +package lis + +import ( + "os" + "testing" +) + +func TestLIS(t *testing.T) { + testData := [][]int{ + {10, 9, 2, 5, 3, 7, 101, 18}, + {}, + } + expectedData := []int{4, 0} + + for index, data := range testData { + if res := lengthOfLIS(data); res != expectedData[index] { + t.Errorf("expected %d, got %d", expectedData[index], res) + } + } +} + +func TestMain(m *testing.M) { + os.Exit(m.Run()) +} diff --git a/src/0343_integer_break/integer_break.go b/src/0343_integer_break/integer_break.go new file mode 100644 index 0000000..45bc07a --- /dev/null +++ b/src/0343_integer_break/integer_break.go @@ -0,0 +1,85 @@ +/* +343. Integer Break +https://leetcode.com/problems/integer-break + +Given a positive integer n, break it into the sum of at least two positive integers and maximize the product of those integers. Return the maximum product you can get. + +Example 1: + +Input: 2 +Output: 1 +Explanation: 2 = 1 + 1, 1 × 1 = 1. +Example 2: + +Input: 10 +Output: 36 +Explanation: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36. +Note: You may assume that n is not less than 2 and not larger than 58. +*/ + +package integerbreak + +import "leetcode/utils" + +// recursion +/* +func integerBreak(n int) int { + if n == 1 { + return 1 + } + + res := utils.MinInt + + for i := 1; i < n; i++ { + res, _ = utils.CalcMaxInt(res, i*(n-i), i*integerBreak(n-i)) + } + return res +} +*/ + +// memory search +/* +func integerBreak(n int) int { + memo := make([]int, n+1) + + for i := 0; i <= n; i++ { + memo[i] = -1 + } + return breakInt(n, memo) +} + +func breakInt(n int, memo []int) int { + if n == 1 { + return 1 + } + + if memo[n] != -1 { + return memo[n] + } + + res := utils.MinInt + for i := 1; i < n; i++ { + res, _ = utils.CalcMaxInt(res, i*(n-i), i*breakInt(n-i, memo)) + } + memo[n] = res + return res +} +*/ + +// dynamic programming +// Time complexity: O(n^2) +// Space complexity: O(n+1) +func integerBreak(n int) int { + // memo[i]表示将数字i分割(至少分割成两部分)后得到的最大乘积. + memo := make([]int, n+1) + + memo[1] = 1 + + for i := 2; i <= n; i++ { + // 求解memo[i] + for j := 1; j <= i-1; j++ { + memo[i] = utils.CalcMaxInt(memo[i], j*(i-j), j*memo[i-j]) + } + } + return memo[n] +} diff --git a/src/0343_integer_break/integer_break_test.go b/src/0343_integer_break/integer_break_test.go new file mode 100644 index 0000000..87dffb4 --- /dev/null +++ b/src/0343_integer_break/integer_break_test.go @@ -0,0 +1,14 @@ +package integerbreak + +import "testing" + +func TestIntegerBreak(t *testing.T) { + testData := []int{2, 10, 34} + expectedData := []int{1, 36, 236196} + + for index, data := range testData { + if res := integerBreak(data); res != expectedData[index] { + t.Errorf("expected %d, got %d", expectedData[index], res) + } + } +} diff --git a/src/0349_intersection_of_2_arrays/intersection_of_two_arrays.go b/src/0349_intersection_of_2_arrays/intersection_of_two_arrays.go new file mode 100644 index 0000000..881220c --- /dev/null +++ b/src/0349_intersection_of_2_arrays/intersection_of_two_arrays.go @@ -0,0 +1,44 @@ +/* +349. Intersection of Two Arrays +https://leetcode.com/problems/intersection-of-two-arrays + +Given two arrays, write a function to compute their intersection. + +Example 1: + +Input: nums1 = [1,2,2,1], nums2 = [2,2] +Output: [2] +Example 2: + +Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4] +Output: [9,4] + +Note: + Each element in the result must be unique. + The result can be in any order. +*/ + +package intersectionof2arrays + +import "leetcode/utils" + +func intersection(nums1 []int, nums2 []int) []int { + set1 := utils.NewSet() + for _, num := range nums1 { + set1.Add(num) + } + set2 := utils.NewSet() + for _, num := range nums2 { + set2.Add(num) + } + + var res []int + for item := range set1 { + if set2.Contains(item) { + if value, ok := item.(int); ok { + res = append(res, value) + } + } + } + return res +} diff --git a/src/0349_intersection_of_2_arrays/intersection_of_two_arrays_test.go b/src/0349_intersection_of_2_arrays/intersection_of_two_arrays_test.go new file mode 100644 index 0000000..f39c9ae --- /dev/null +++ b/src/0349_intersection_of_2_arrays/intersection_of_two_arrays_test.go @@ -0,0 +1,16 @@ +package intersectionof2arrays + +import ( + "reflect" + "testing" +) + +func TestIntersection(t *testing.T) { + nums1 := []int{1, 2, 2, 1} + nums2 := []int{2, 2} + expectedData := []int{2} + + if res := intersection(nums1, nums2); !reflect.DeepEqual(res, expectedData) { + t.Errorf("expected %v, got %v", expectedData, res) + } +} diff --git a/src/0350_intersection_of_two_arrays2/intersection_of_two_arrays2.go b/src/0350_intersection_of_two_arrays2/intersection_of_two_arrays2.go new file mode 100644 index 0000000..5858209 --- /dev/null +++ b/src/0350_intersection_of_two_arrays2/intersection_of_two_arrays2.go @@ -0,0 +1,27 @@ +/* +350. Intersection of Two Arrays II +https://leetcode.com/problems/intersection-of-two-arrays-ii/ + +*/ + +package intersectionof2arrays2 + +func intersect(nums1 []int, nums2 []int) []int { + record := make(map[int]int) + res := make([]int, 0) + for _, num := range nums1 { + if _, ok := record[num]; !ok { + record[num] = 1 + } else { + record[num]++ + } + } + + for _, num := range nums2 { + if count, ok := record[num]; ok && count > 0 { + res = append(res, num) + record[num]-- + } + } + return res +} diff --git a/src/0350_intersection_of_two_arrays2/intersection_of_two_arrays2_test.go b/src/0350_intersection_of_two_arrays2/intersection_of_two_arrays2_test.go new file mode 100644 index 0000000..0b809e8 --- /dev/null +++ b/src/0350_intersection_of_two_arrays2/intersection_of_two_arrays2_test.go @@ -0,0 +1,17 @@ +package intersectionof2arrays2 + +import ( + "reflect" + "testing" +) + +func TestInteract(t *testing.T) { + nums1 := []int{1, 2, 2, 1} + nums2 := []int{2, 2} + + expectedData := []int{2, 2} + + if res := intersect(nums1, nums2); !reflect.DeepEqual(res, expectedData) { + t.Errorf("expected %v, got %v", expectedData, res) + } +} diff --git a/src/0376_wiggle_subsequence/wiggle_subsequence.go b/src/0376_wiggle_subsequence/wiggle_subsequence.go new file mode 100644 index 0000000..bc37067 --- /dev/null +++ b/src/0376_wiggle_subsequence/wiggle_subsequence.go @@ -0,0 +1,70 @@ +/* +376. Wiggle Subsequence +https://leetcode.com/problems/wiggle-subsequence/ + +A sequence of numbers is called a wiggle sequence if the differences between successive numbers strictly alternate between positive and negative. The first difference (if one exists) may be either positive or negative. A sequence with fewer than two elements is trivially a wiggle sequence. + +For example, [1,7,4,9,2,5] is a wiggle sequence because the differences (6,-3,5,-7,3) are alternately positive and negative. In contrast, [1,4,7,2,5] and [1,7,4,5,5] are not wiggle sequences, the first because its first two differences are positive and the second because its last difference is zero. + +Given a sequence of integers, return the length of the longest subsequence that is a wiggle sequence. A subsequence is obtained by deleting some number of elements (eventually, also zero) from the original sequence, leaving the remaining elements in their original order. + +Example 1: + +Input: [1,7,4,9,2,5] +Output: 6 +Explanation: The entire sequence is a wiggle sequence. +Example 2: + +Input: [1,17,5,10,13,15,10,5,16,8] +Output: 7 +Explanation: There are several subsequences that achieve this length. One is [1,17,10,13,10,16,8]. +Example 3: + +Input: [1,2,3,4,5,6,7,8,9] +Output: 2 + +Follow up: +Can you do it in O(n) time? +*/ + +package wigglesubsequence + +import "leetcode/utils" + +/* + * 用up[i]和down[i]分别记录到第i个元素为止以上升沿和下降沿结束的最长“摆动” + * 序列长度,遍历数组,如果nums[i]>nums[i-1],表明第i-1到第i个元素是上升的, + * 因此up[i]只需在down[i-1]的基础上加1即可,而down[i]保持down[i-1]不变; + * 如果nums[i] O(n) +func wiggleMaxLength(nums []int) int { + n := len(nums) + + if n == 1 || n == 0 { + return n + } + + up := make([]int, n) + for i := 0; i < n; i++ { + up[i] = 1 + } + down := make([]int, n) + copy(down, up) + + for i := 1; i < n; i++ { + for j := 0; j < i; j++ { + if nums[i] > nums[j] { + up[i] = utils.CalcMaxInt(up[i], down[j]+1) + } else if nums[i] < nums[j] { + down[i] = utils.CalcMaxInt(down[i], up[j]+1) + } + } + } + return utils.CalcMaxInt(up[n-1], down[n-1]) +} diff --git a/src/0376_wiggle_subsequence/wiggle_subsequence_test.go b/src/0376_wiggle_subsequence/wiggle_subsequence_test.go new file mode 100644 index 0000000..1f9c119 --- /dev/null +++ b/src/0376_wiggle_subsequence/wiggle_subsequence_test.go @@ -0,0 +1,50 @@ +package wigglesubsequence + +import "testing" + +func TestWiggleSubsequence(t *testing.T) { + testData := [][]int{ + {1, 17, 5, 10, 13, 15, 10, 5, 16, 8}, + {1, 7, 4, 9, 2, 5}, + {1, 2, 3, 4, 5, 6, 7, 8, 9}, + {}, + {2}, + {3, 4}, + {3, 3, 3, 2, 5}, + { + 372, 492, 288, 399, 81, 2, 320, 94, 416, 469, 427, 117, 265, 357, 399, 456, 496, 337, 355, 219, 475, 295, 457, + 350, 490, 470, 281, 127, 131, 36, 430, 412, 442, 174, 128, 253, 1, 56, 306, 295, 340, 73, 253, 130, 259, 223, 14, + 79, 409, 384, 209, 151, 317, 441, 156, 275, 140, 224, 128, 250, 290, 191, 161, 472, 477, 125, 470, 230, 321, 5, 311, + 23, 27, 248, 138, 284, 215, 356, 320, 194, 434, 136, 221, 273, 450, 440, 28, 179, 36, 386, 482, 203, 24, 8, 391, 21, + 500, 484, 135, 348, 292, 396, 145, 443, 406, 61, 212, 480, 455, 78, 309, 318, 84, 474, 209, 225, 177, 356, 227, 263, + 181, 476, 478, 151, 494, 395, 23, 114, 395, 429, 450, 247, 245, 150, 354, 230, 100, 172, 454, 155, 189, 33, 290, 187, + 443, 123, 59, 358, 241, 141, 39, 196, 491, 381, 157, 157, 134, 431, 295, 20, 123, 118, 207, 199, 317, 188, 267, 335, 315, + 308, 115, 321, 56, 52, 253, 492, 97, 374, 398, 272, 74, 206, 109, 172, 471, 55, 452, 452, 329, 367, 372, 252, 99, 62, 122, + 287, 320, 325, 307, 481, 316, 378, 87, 97, 457, 21, 312, 249, 354, 286, 196, 43, 170, 500, 265, 253, 19, 480, 438, 113, + 473, 247, 257, 33, 395, 456, 246, 310, 469, 408, 112, 385, 53, 449, 117, 122, 210, 286, 149, 20, 364, 372, 71, 26, 155, + 292, 16, 72, 384, 160, 79, 241, 346, 230, 15, 427, 96, 95, 59, 151, 325, 490, 223, 131, 81, 294, 18, 70, 171, 339, 14, 40, + 463, 421, 355, 123, 408, 357, 202, 235, 390, 344, 198, 98, 361, 434, 174, 216, 197, 274, 231, 85, 494, 57, 136, 258, 134, + 441, 477, 456, 318, 155, 138, 461, 65, 426, 162, 90, 342, 284, 374, 204, 464, 9, 280, 391, 491, 231, 298, 284, 82, 417, 355, + 356, 207, 367, 262, 244, 283, 489, 477, 143, 495, 472, 372, 447, 322, 399, 239, 450, 168, 202, 89, 333, 276, 199, 416, 490, + 494, 488, 137, 327, 113, 189, 430, 320, 197, 120, 71, 262, 31, 295, 218, 74, 238, 169, 489, 308, 300, 260, 397, 308, 328, 267, + 419, 84, 357, 486, 289, 312, 230, 64, 468, 227, 268, 28, 243, 267, 254, 153, 407, 399, 346, 385, 77, 297, 273, 484, 366, 482, + 491, 368, 221, 423, 107, 272, 98, 309, 426, 181, 320, 77, 185, 382, 478, 398, 476, 22, 328, 450, 299, 211, 285, 62, 344, 484, 395, + 466, 291, 487, 301, 407, 28, 295, 36, 429, 99, 462, 240, 124, 261, 387, 30, 362, 161, 156, 184, 188, 99, 377, 392, 442, 300, 98, 285, + 312, 312, 365, 415, 367, 105, 81, 378, 413, 43, 326, 490, 320, 266, 390, 53, 327, 75, 332, 454, 29, 370, 392, 360, 1, 335, 355, 344, 120, + 417, 455, 93, 60, 256, 451, 188, 161, 388, 338, 238, 26, 275, 340, 109, 185, + }, + } + + expectedData := []int{ + 7, 6, 2, + 0, + 1, + 2, 3, 334, + } + + for index, data := range testData { + if res := wiggleMaxLength(data); res != expectedData[index] { + t.Errorf("expected %d, got %d", expectedData[index], res) + } + } +} diff --git a/src/0392_is_subsequence/is_subsequence.go b/src/0392_is_subsequence/is_subsequence.go new file mode 100644 index 0000000..9c45346 --- /dev/null +++ b/src/0392_is_subsequence/is_subsequence.go @@ -0,0 +1,45 @@ +/* +392. Is Subsequence +https://leetcode.com/problems/is-subsequence/ + +Given a string s and a string t, check if s is subsequence of t. + +You may assume that there is only lower case English letters in both s and t. t is potentially a very long (length ~= 500,000) string, and s is a short string (<=100). + +A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie, "ace" is a subsequence of "abcde" while "aec" is not). + +Example 1: +s = "abc", t = "ahbgdc" + +Return true. + +Example 2: +s = "axc", t = "ahbgdc" + +Return false. + +Follow up: +If there are lots of incoming S, say S1, S2, ... , Sk where k >= 1B, and you want to check one by one to see if T has its subsequence. In this scenario, how would you change your code? + +Credits: +Special thanks to @pbrother for adding this problem and creating all test cases. +*/ + +package issubsequence + +// greedy +// Time complexity: O(n), where n is min( len(s), len(t) ) +// Space complexity: O(1) +func isSubsequence(s string, t string) bool { + var si, ti int + + for si < len(s) && ti < len(t) { + if s[si] == t[ti] { + si++ + ti++ + } else { + ti++ + } + } + return si == len(s) +} diff --git a/src/0392_is_subsequence/is_subsequence_test.go b/src/0392_is_subsequence/is_subsequence_test.go new file mode 100644 index 0000000..d5dfa2d --- /dev/null +++ b/src/0392_is_subsequence/is_subsequence_test.go @@ -0,0 +1,28 @@ +package issubsequence + +import "testing" + +type args struct { + s string + t string +} + +func TestAssignCookies(t *testing.T) { + testData := []args{ + args{ + s: "abc", + t: "ahbgdc", + }, + args{ + s: "acb", + t: "ahbgdc", + }, + } + expectedData := []bool{true, false} + + for index, data := range testData { + if res := isSubsequence(data.s, data.t); res != expectedData[index] { + t.Errorf("expected %t, got %t", expectedData[index], res) + } + } +} diff --git a/src/0416_partition_equal_subset_sum/partition_equal_subset_sum.go b/src/0416_partition_equal_subset_sum/partition_equal_subset_sum.go new file mode 100644 index 0000000..b48748b --- /dev/null +++ b/src/0416_partition_equal_subset_sum/partition_equal_subset_sum.go @@ -0,0 +1,47 @@ +/* +416. Partition Equal Subset Sum +https://leetcode.com/problems/partition-equal-subset-sum/ + +Given a non-empty array containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal. + +Note: + 1. Each of the array element will not exceed 100. + 2. The array size will not exceed 200. +*/ + +package partitionequalsubsetsum + +/* +此问题可以使用0-1背包问题的思路求解 + +c是数组和的一半。 + +状态定义:F(n c) + +状态转移方程:F(n c) = max( F(n-1, c) , n + F(n-1, c-n) ) +*/ +func canPartition(nums []int) bool { + var sum int + for _, num := range nums { + sum += num + } + + if sum%2 != 0 { + return false + } + + c := sum / 2 + n := len(nums) + memo := make([]bool, c+1) + + for i := 0; i <= c; i++ { + memo[i] = nums[0] == i + } + + for i := 0; i < n; i++ { + for j := c; j >= nums[i]; j-- { + memo[j] = memo[j] || memo[j-nums[i]] + } + } + return memo[c] +} diff --git a/src/0416_partition_equal_subset_sum/partition_equal_subset_sum_test.go b/src/0416_partition_equal_subset_sum/partition_equal_subset_sum_test.go new file mode 100644 index 0000000..51dcb82 --- /dev/null +++ b/src/0416_partition_equal_subset_sum/partition_equal_subset_sum_test.go @@ -0,0 +1,18 @@ +package partitionequalsubsetsum + +import "testing" + +func TestPartitionEqualSubsetSum(t *testing.T) { + testData := [][]int{ + {1, 5, 11, 5}, + {1, 2, 3, 5}, + } + + expectedData := []bool{true, false} + + for index, data := range testData { + if res := canPartition(data); res != expectedData[index] { + t.Errorf("expected %t, got %t", expectedData[index], res) + } + } +} diff --git a/src/0435_non_overlapping_intervals/dp_solution.go b/src/0435_non_overlapping_intervals/dp_solution.go new file mode 100644 index 0000000..ad31424 --- /dev/null +++ b/src/0435_non_overlapping_intervals/dp_solution.go @@ -0,0 +1,47 @@ +/* +435. Non-overlapping Intervals +https://leetcode.com/problems/non-overlapping-intervals/ + +Given a collection of intervals, find the minimum number of intervals you need to remove to make the rest of the intervals non-overlapping. + +Note: + 1. You may assume the interval's end point is always bigger than its start point. + 2. Intervals like [1,2] and [2,3] have borders "touching" but they don't overlap each other. +*/ + +package nonoverlappingintervals + +import ( + "leetcode/utils" + "sort" +) + +func eraseOverlapIntervalsDp(intervals []Interval) int { + n := len(intervals) + if n == 0 { + return 0 + } + + sort.Sort(IntervalSliceCompareWithStart(intervals)) + + // memo[i]表示使用intervals[0...i]的区间能构成的最长不重叠区间序列 + memo := make([]int, n) + for i := 0; i < n; i++ { + memo[i] = 1 + } + + for i := 1; i < n; i++ { + // memo[i] + for j := 0; j < i; j++ { + if intervals[i].Start >= intervals[j].End { + memo[i] = utils.CalcMaxInt(memo[i], 1+memo[j]) + } + } + } + + var res int + for i := 0; i < n; i++ { + res = utils.CalcMaxInt(res, memo[i]) + } + return n - res +} diff --git a/src/0435_non_overlapping_intervals/greedy_solution.go b/src/0435_non_overlapping_intervals/greedy_solution.go new file mode 100644 index 0000000..ddf23d9 --- /dev/null +++ b/src/0435_non_overlapping_intervals/greedy_solution.go @@ -0,0 +1,35 @@ +/* +435. Non-overlapping Intervals +https://leetcode.com/problems/non-overlapping-intervals/ + +Given a collection of intervals, find the minimum number of intervals you need to remove to make the rest of the intervals non-overlapping. + +Note: + 1. You may assume the interval's end point is always bigger than its start point. + 2. Intervals like [1,2] and [2,3] have borders "touching" but they don't overlap each other. +*/ + +package nonoverlappingintervals + +import "sort" + +func eraseOverlapIntervalsGreedy(intervals []Interval) int { + n := len(intervals) + if n == 0 { + return 0 + } + + sort.Sort(IntervalSliceCompareWithEnd(intervals)) + var ( + res = 1 + pre = 0 + ) + + for i := 1; i < n; i++ { + if intervals[i].Start >= intervals[pre].End { + res++ + pre = i + } + } + return n - res +} diff --git a/src/0435_non_overlapping_intervals/interval.go b/src/0435_non_overlapping_intervals/interval.go new file mode 100644 index 0000000..25b2005 --- /dev/null +++ b/src/0435_non_overlapping_intervals/interval.go @@ -0,0 +1,39 @@ +package nonoverlappingintervals + +// Interval Definition for an interval. +type Interval struct { + Start int + End int +} + +// IntervalSliceCompareWithStart slice of Interval sort with start +type IntervalSliceCompareWithStart []Interval + +// Len is the number of elements in the collection. +func (i IntervalSliceCompareWithStart) Len() int { return len(i) } + +// Less compare Interval with start +func (i IntervalSliceCompareWithStart) Less(j, k int) bool { + if i[j].Start != i[k].Start { + return i[j].Start < i[k].Start + } + return i[j].End < i[k].End +} + +func (i IntervalSliceCompareWithStart) Swap(j, k int) { i[j], i[k] = i[k], i[j] } + +// IntervalSliceCompareWithEnd slice of Interval sort with end +type IntervalSliceCompareWithEnd []Interval + +// Len is the number of elements in the collection. +func (i IntervalSliceCompareWithEnd) Len() int { return len(i) } + +// Less compare Interval with end +func (i IntervalSliceCompareWithEnd) Less(j, k int) bool { + if i[j].End != i[k].End { + return i[j].End < i[k].End + } + return i[j].Start < i[k].Start +} + +func (i IntervalSliceCompareWithEnd) Swap(j, k int) { i[j], i[k] = i[k], i[j] } diff --git a/src/0435_non_overlapping_intervals/solution_test.go b/src/0435_non_overlapping_intervals/solution_test.go new file mode 100644 index 0000000..effb50d --- /dev/null +++ b/src/0435_non_overlapping_intervals/solution_test.go @@ -0,0 +1,37 @@ +package nonoverlappingintervals + +import "testing" + +func TestEraseOverlapIntervals(t *testing.T) { + testData := [][]Interval{ + { + Interval{Start: 1, End: 2}, + Interval{Start: 1, End: 2}, + Interval{Start: 1, End: 2}, + }, + { + Interval{Start: 1, End: 2}, + Interval{Start: 2, End: 3}, + }, + { + Interval{Start: 1, End: 2}, + Interval{Start: 2, End: 3}, + Interval{Start: 3, End: 4}, + Interval{Start: 1, End: 3}, + }, + } + expectedData := []int{2, 0, 1} + + testFuncs := []func([]Interval) int{ + eraseOverlapIntervalsGreedy, + eraseOverlapIntervalsDp, + } + + for index, data := range testData { + for _, testFunc := range testFuncs { + if res := testFunc(data); res != expectedData[index] { + t.Errorf("expected %d, got %d", expectedData[index], res) + } + } + } +} diff --git a/src/0438_all_anagrams_in_a_string/all_anagrams_in_a_string.go b/src/0438_all_anagrams_in_a_string/all_anagrams_in_a_string.go new file mode 100644 index 0000000..d71b451 --- /dev/null +++ b/src/0438_all_anagrams_in_a_string/all_anagrams_in_a_string.go @@ -0,0 +1,82 @@ +/* +Source: https://leetcode.com/problems/find-all-anagrams-in-a-string/submissions/ + +Given a string s and a non-empty string p, find all the start indices of p's anagrams in s. + +Strings consists of lowercase English letters only and the length of both strings s and p will not be larger than 20,100. + +The order of output does not matter. + +Example 1: + +Input: +s: "cbaebabacd" p: "abc" + +Output: +[0, 6] + +Explanation: +The substring with start index = 0 is "cba", which is an anagram of "abc". +The substring with start index = 6 is "bac", which is an anagram of "abc". +Example 2: + +Input: +s: "abab" p: "ab" + +Output: +[0, 1, 2] + +Explanation: +The substring with start index = 0 is "ab", which is an anagram of "ab". +The substring with start index = 1 is "ba", which is an anagram of "ab". +The substring with start index = 2 is "ab", which is an anagram of "ab". + +Time: 2018-12-17 +*/ + +package allanagramsinastring + +// Sliding Window +// Time complexity: O(len(p) + len(s)) = O(n) +// Space complexity: O(1) +func findAnagrams(s string, p string) []int { + var ( + lenS = len(s) + lenP = len(p) + res = []int{} + freqP = make([]int, 26) + freqS = make([]int, 26) + left int + right = -1 // Sliding window: s[left, right] + ) + + if lenS < lenP { + return res + } + + for i := 0; i < lenP; i++ { + freqP[p[i]-'a']++ + } + + for right+1 < lenS { + right++ + freqS[s[right]-'a']++ + if right-left+1 > lenP { + freqS[s[left]-'a']-- + left++ + } + if right-left+1 == lenP && isSame(freqP, freqS) { + res = append(res, left) + } + } + return res +} + +func isSame(p []int, q []int) bool { + for i := 0; i < 26; i++ { + if p[i] != q[i] { + return false + } + } + return true +} diff --git a/src/0438_all_anagrams_in_a_string/all_anagrams_in_a_string_test.go b/src/0438_all_anagrams_in_a_string/all_anagrams_in_a_string_test.go new file mode 100644 index 0000000..4e75dc1 --- /dev/null +++ b/src/0438_all_anagrams_in_a_string/all_anagrams_in_a_string_test.go @@ -0,0 +1,39 @@ +package allanagramsinastring + +import ( + "reflect" + "testing" +) + +func TestFindAnagrams(t *testing.T) { + type arg struct { + s string + p string + } + cases := []arg{ + arg{ + s: "cbaebabacd", + p: "abc", + }, + arg{ + s: "abab", + p: "ab", + }, + arg{ + p: "abab", + s: "ab", + }, + } + + expected := [][]int{ + {0, 6}, + {0, 1, 2}, + {}, + } + + for index, args := range cases { + if res := findAnagrams(args.s, args.p); !reflect.DeepEqual(res, expected[index]) { + t.Errorf("expected %v, got %v", expected[index], res) + } + } +} diff --git a/src/0447_number_of_boomerangs/number_of_boomerangs.go b/src/0447_number_of_boomerangs/number_of_boomerangs.go new file mode 100644 index 0000000..82a9937 --- /dev/null +++ b/src/0447_number_of_boomerangs/number_of_boomerangs.go @@ -0,0 +1,42 @@ +/* +447. Number of Boomerangs +https://leetcode.com/problems/number-of-boomerangs/ + +Given n points in the plane that are all pairwise distinct, a "boomerang" is a tuple of points (i, j, k) such that the distance between i and j equals the distance between i and k (the order of the tuple matters). + +Find the number of boomerangs. You may assume that n will be at most 500 and coordinates of points are all in the range [-10000, 10000] (inclusive). +*/ + +package numberofboomerangs + +import ( + "math" +) + +// Time complexity: O(n^2) +// Space complexity: O(n) +func numberOfBoomerangs(points [][]int) int { + var ( + res int + n = len(points) + ) + + for i := 0; i < n; i++ { + record := make(map[int]int) + for j := 0; j < n; j++ { + if j != i { + dis := dis(points[i], points[j]) + record[dis]++ + } + } + + for _, j := range record { + res += j * (j - 1) + } + } + return res +} + +func dis(point1 []int, point2 []int) int { + return int(math.Pow(float64(point1[0]-point2[0]), float64(2)) + math.Pow(float64(point1[1]-point2[1]), float64(2))) +} diff --git a/src/0447_number_of_boomerangs/number_of_boomerangs_test.go b/src/0447_number_of_boomerangs/number_of_boomerangs_test.go new file mode 100644 index 0000000..2ae6b76 --- /dev/null +++ b/src/0447_number_of_boomerangs/number_of_boomerangs_test.go @@ -0,0 +1,61 @@ +package numberofboomerangs + +import "testing" + +func TestNumberOfBoomerangs(t *testing.T) { + testData := [][]int{ + {489, 238}, {323, 460}, {853, 965}, {327, 426}, {264, 871}, {580, 947}, {362, 275}, {241, 772}, {967, 240}, {68, 847}, + {825, 703}, {922, 898}, {769, 217}, {23, 160}, {472, 802}, {755, 313}, {40, 78}, {125, 246}, {396, 452}, {672, 660}, + {323, 253}, {607, 37}, {880, 201}, {161, 847}, {441, 229}, {46, 266}, {284, 320}, {516, 53}, {889, 539}, {565, 713}, + {341, 320}, {26, 381}, {751, 504}, {979, 147}, {956, 652}, {807, 632}, {257, 767}, {669, 489}, {968, 831}, {336, 409}, + {60, 734}, {27, 697}, {54, 543}, {750, 944}, {82, 668}, {657, 423}, {988, 36}, {156, 91}, {540, 136}, {238, 496}, {140, 398}, + {128, 397}, {165, 150}, {238, 133}, {981, 926}, {894, 393}, {660, 921}, {90, 66}, {464, 193}, {10, 898}, {861, 20}, {321, 201}, + {408, 829}, {293, 948}, {965, 531}, {796, 457}, {929, 277}, {206, 446}, {427, 444}, {931, 760}, {370, 825}, {153, 30}, + {98, 244}, {449, 914}, {789, 811}, {812, 650}, {831, 485}, {203, 239}, {315, 496}, {539, 632}, {380, 336}, {442, 661}, + {613, 648}, {108, 392}, {93, 391}, {152, 815}, {217, 305}, {198, 667}, {901, 647}, {934, 690}, {458, 746}, {692, 642}, + {584, 896}, {233, 251}, {744, 773}, {235, 124}, {109, 677}, {786, 74}, {326, 246}, {466, 771}, {989, 618}, {586, 558}, + {923, 136}, {226, 177}, {783, 160}, {867, 594}, {258, 912}, {236, 842}, {808, 469}, {445, 552}, {242, 681}, {29, 703}, + {358, 167}, {777, 36}, {765, 595}, {807, 754}, {213, 746}, {313, 489}, {882, 539}, {666, 18}, {51, 885}, {612, 309}, + {149, 200}, {504, 957}, {669, 949}, {862, 264}, {630, 891}, {319, 341}, {410, 449}, {377, 175}, {44, 537}, {929, 610}, + {635, 242}, {99, 869}, {133, 117}, {887, 184}, {354, 851}, {846, 504}, {51, 350}, {813, 73}, {651, 675}, {337, 634}, + {918, 656}, {975, 328}, {105, 704}, {503, 502}, {241, 785}, {112, 876}, {27, 211}, {98, 513}, {680, 985}, {697, 386}, + {189, 895}, {890, 240}, {245, 56}, {313, 897}, {83, 2}, {531, 2}, {659, 858}, {682, 116}, {562, 538}, {618, 804}, {323, 730}, + {32, 702}, {293, 482}, {215, 325}, {468, 265}, {64, 657}, {160, 306}, {249, 406}, {362, 915}, {655, 446}, {917, 538}, + {800, 576}, {396, 482}, {45, 310}, {20, 15}, {466, 343}, {98, 851}, {46, 743}, {333, 261}, {421, 801}, {878, 485}, {810, 39}, + {791, 412}, {797, 154}, {327, 452}, {600, 244}, {342, 400}, {173, 90}, {234, 570}, {400, 255}, {585, 867}, {950, 683}, + {718, 996}, {779, 51}, {610, 200}, {205, 488}, {685, 367}, {879, 476}, {779, 676}, {982, 458}, {128, 934}, {703, 822}, + {686, 228}, {912, 921}, {798, 313}, {176, 735}, {180, 478}, {771, 898}, {475, 550}, {301, 437}, {750, 506}, {277, 787}, + {226, 157}, {615, 5}, {833, 598}, {816, 314}, {532, 519}, {136, 219}, {99, 49}, {492, 249}, {362, 20}, {984, 894}, {498, 755}, + {144, 325}, {657, 445}, {762, 407}, {304, 392}, {546, 530}, {549, 162}, {887, 734}, {760, 703}, {48, 644}, {574, 537}, + {215, 673}, {938, 707}, {922, 652}, {727, 259}, {546, 226}, {14, 42}, {551, 24}, {487, 666}, {783, 143}, {58, 330}, {673, 959}, + {492, 913}, {693, 604}, {616, 94}, {248, 191}, {631, 816}, {216, 569}, {523, 491}, {573, 603}, {750, 119}, {181, 116}, {513, 84}, + {140, 0}, {750, 924}, {496, 160}, {254, 521}, {119, 98}, {434, 165}, {702, 51}, {259, 302}, {594, 242}, {118, 810}, {163, 994}, + {653, 736}, {597, 403}, {207, 778}, {520, 720}, {862, 12}, {72, 965}, {936, 568}, {125, 542}, {442, 597}, {640, 876}, {762, 694}, + {279, 373}, {997, 225}, {967, 467}, {388, 130}, {461, 41}, {218, 410}, {445, 425}, {540, 317}, {497, 403}, {329, 569}, {720, 266}, {490, 197}, + {808, 932}, {146, 801}, {160, 260}, {495, 440}, {633, 844}, {17, 600}, {312, 405}, {82, 125}, {447, 300}, {536, 244}, {77, 76}, {561, 574}, {831, 890}, + {144, 903}, {508, 986}, {101, 669}, {918, 599}, {470, 78}, {860, 965}, {870, 845}, {810, 888}, {446, 122}, {645, 880}, {599, 92}, {181, 487}, {688, 610}, + {916, 249}, {185, 747}, {492, 681}, {3, 352}, {667, 456}, {21, 937}, {55, 491}, {15, 915}, {457, 238}, {761, 267}, {478, 559}, {741, 123}, + {439, 692}, {568, 972}, {180, 256}, {935, 96}, {858, 120}, {195, 702}, {801, 198}, {54, 820}, {654, 76}, {757, 62}, + {567, 772}, {977, 376}, {362, 90}, {995, 840}, {1, 88}, {316, 793}, {781, 884}, {765, 961}, {492, 700}, {57, 702}, + {172, 604}, {404, 325}, {803, 459}, {145, 809}, {887, 902}, {871, 454}, {27, 201}, {183, 741}, {643, 178}, {582, 645}, + {267, 250}, {438, 48}, {134, 555}, {361, 978}, {608, 770}, {681, 780}, {374, 437}, {106, 529}, {896, 603}, {339, 135}, + {858, 562}, {590, 885}, {115, 125}, {626, 759}, {303, 560}, {404, 922}, {810, 842}, {970, 296}, {397, 683}, {627, 5}, + {453, 308}, {138, 828}, {745, 596}, {709, 994}, {199, 48}, {129, 57}, {963, 71}, {294, 78}, {196, 273}, {189, 852}, + {833, 593}, {774, 996}, {787, 97}, {644, 537}, {780, 271}, {894, 234}, {579, 32}, {414, 677}, {628, 123}, {23, 180}, {524, 504}, + {589, 487}, {576, 884}, {917, 124}, {157, 107}, {976, 342}, {52, 103}, {690, 840}, {200, 335}, {377, 980}, {606, 271}, + {566, 538}, {656, 980}, {567, 636}, {456, 590}, {168, 980}, {94, 758}, {819, 22}, {994, 88}, {147, 503}, {195, 475}, {197, 600}, + {578, 888}, {792, 130}, {223, 169}, {463, 181}, {792, 29}, {719, 800}, {10, 286}, {789, 466}, {228, 957}, {798, 323}, + {715, 617}, {697, 61}, {705, 196}, {564, 253}, {672, 762}, {205, 602}, {650, 997}, {85, 225}, {518, 548}, {406, 662}, + {577, 478}, {463, 939}, {116, 252}, {757, 345}, {561, 555}, {20, 277}, {524, 717}, {690, 582}, {914, 255}, {187, 938}, + {17, 392}, {892, 19}, {741, 977}, {596, 259}, {525, 2}, {273, 455}, {832, 736}, {394, 949}, {340, 504}, {294, 902}, + {59, 314}, {531, 936}, {383, 221}, {870, 297}, {828, 57}, {587, 197}, {801, 480}, {568, 894}, {457, 164}, {153, 335}, + {519, 426}, {790, 351}, {515, 536}, {652, 207}, {40, 946}, {461, 452}, {612, 344}, {388, 996}, {918, 610}, {645, 746}, {19, 233}, {296, 820}, + {65, 864}, {66, 522}, {29, 219}, {209, 548}, {997, 351}, {251, 864}, {888, 904}, {72, 928}, {202, 885}, {732, 815}, {230, 472}, + {163, 148}, {82, 160}, {246, 101}, {745, 542}, {273, 810}, {407, 339}, + } + expectedData := 1000 + + if res := numberOfBoomerangs(testData); res != expectedData { + t.Errorf("expected %d, got %d", expectedData, res) + } +} diff --git a/src/0454_4sum2/4sum2.go b/src/0454_4sum2/4sum2.go new file mode 100644 index 0000000..69b601c --- /dev/null +++ b/src/0454_4sum2/4sum2.go @@ -0,0 +1,34 @@ +/* +454. 4Sum II +https://leetcode.com/problems/4sum-ii/ + +Given four lists A, B, C, D of integer values, compute how many tuples (i, j, k, l) there are such that A[i] + B[j] + C[k] + D[l] is zero. + +To make problem a bit easier, all A, B, C, D have same length of N where 0 ≤ N ≤ 500. All integers are in the range of -228 to 228 - 1 and the result is guaranteed to be at most 231 - 1. +*/ + +package foursum2 + +// Time complexity: O(n^2) +// Space complexity: O(n^2) +func fourSumCount(A []int, B []int, C []int, D []int) int { + var ( + record = make(map[int]int) + res int + ) + + for _, i := range A { + for _, j := range B { + record[i+j]++ + } + } + + for _, i := range C { + for _, j := range D { + if s, ok := record[-i-j]; ok && s > 0 { + res += s + } + } + } + return res +} diff --git a/src/0454_4sum2/4sum2_test.go b/src/0454_4sum2/4sum2_test.go new file mode 100644 index 0000000..9517001 --- /dev/null +++ b/src/0454_4sum2/4sum2_test.go @@ -0,0 +1,16 @@ +package foursum2 + +import "testing" + +func TestFourSumCount(t *testing.T) { + A := []int{1, 2} + B := []int{-2, -1} + C := []int{-1, 2} + D := []int{0, 2} + + expectedData := 2 + + if res := fourSumCount(A, B, C, D); res != expectedData { + t.Errorf("expected %d, got %d", expectedData, res) + } +} diff --git a/src/0455_assign_cookies/assign_cookies.go b/src/0455_assign_cookies/assign_cookies.go new file mode 100644 index 0000000..db4c699 --- /dev/null +++ b/src/0455_assign_cookies/assign_cookies.go @@ -0,0 +1,42 @@ +/* +455. Assign Cookies +https://leetcode.com/problems/assign-cookies/ + +Assume you are an awesome parent and want to give your children some cookies. +But, you should give each child at most one cookie. +Each child i has a greed factor gi, which is the minimum size of a cookie that the child will be content with; +and each cookie j has a size sj. If sj >= gi, we can assign the cookie j to the child i, and the child i will be content. +Your goal is to maximize the number of your content children and output the maximum number. + +Note: + 1. You may assume the greed factor is always positive. + 2. You cannot assign more than one cookie to one child. +*/ + +package assigncookies + +import "sort" + +// greedy +// Time complexity: O(n), where n is min ( len(g), len(s) ) +// Space complexity: O(1) +func findContentChildren(g []int, s []int) int { + sort.Sort(sort.Reverse(sort.IntSlice(s))) + sort.Sort(sort.Reverse(sort.IntSlice(g))) + + var ( + si, gi, res int + ) + + for gi < len(g) && si < len(s) { + if s[si] >= g[gi] { + res++ + gi++ + si++ + } else { + gi++ + } + } + + return res +} diff --git a/src/0455_assign_cookies/assign_cookies_test.go b/src/0455_assign_cookies/assign_cookies_test.go new file mode 100644 index 0000000..3dfa60f --- /dev/null +++ b/src/0455_assign_cookies/assign_cookies_test.go @@ -0,0 +1,28 @@ +package assigncookies + +import "testing" + +type args struct { + g []int + s []int +} + +func TestAssignCookies(t *testing.T) { + testData := []args{ + args{ + g: []int{1, 2, 3}, + s: []int{1, 1}, + }, + args{ + g: []int{1, 2}, + s: []int{1, 2, 3}, + }, + } + expectedData := []int{1, 2} + + for index, data := range testData { + if res := findContentChildren(data.g, data.s); res != expectedData[index] { + t.Errorf("expected %d, got %d", expectedData[index], res) + } + } +} diff --git a/src/0728_self_dividing_numbers/self_dividing_numbers.go b/src/0728_self_dividing_numbers/self_dividing_numbers.go new file mode 100644 index 0000000..dd14f07 --- /dev/null +++ b/src/0728_self_dividing_numbers/self_dividing_numbers.go @@ -0,0 +1,48 @@ +/* +728. Self Dividing Numbers + +Source: https://leetcode.com/problems/self-dividing-numbers/ + +A self-dividing number is a number that is divisible by every digit it contains. + +For example, 128 is a self-dividing number because 128 % 1 == 0, 128 % 2 == 0, and 128 % 8 == 0. + +Also, a self-dividing number is not allowed to contain the digit zero. + +Given a lower and upper number bound, output a list of every possible self dividing number, including the bounds if possible. + +Example 1: +Input: +left = 1, right = 22 +Output: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 15, 22] +Note: + +The boundaries of each input argument are 1 <= left <= right <= 10000. + +Time: 2018-12-18 +*/ + +package selfdividingnumbers + +import "strconv" + +//Time complexity: O(right-left+1) +// Space complexity: O(1) +func selfDividingNumbers(left int, right int) []int { + res := make([]int, 0) + + for num := left; num <= right; num++ { + flag := true + strNum := strconv.Itoa(num) + + for j := 0; j < len(strNum); j++ { + if divisor := int(strNum[j] - '0'); divisor == 0 || num%divisor != 0 { + flag = false + } + } + if flag { + res = append(res, num) + } + } + return res +} diff --git a/src/0728_self_dividing_numbers/self_dividing_numbers_test.go b/src/0728_self_dividing_numbers/self_dividing_numbers_test.go new file mode 100644 index 0000000..ce07e07 --- /dev/null +++ b/src/0728_self_dividing_numbers/self_dividing_numbers_test.go @@ -0,0 +1,13 @@ +package selfdividingnumbers + +import ( + "reflect" + "testing" +) + +func TestSelfDividingNumbers(t *testing.T) { + expected := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 15, 22} + if res := selfDividingNumbers(1, 22); !reflect.DeepEqual(res, expected) { + t.Errorf("expected %v, got %v", expected, res) + } +} diff --git a/src/0747_largest_number_at_least_twice_of_others/largest_number_at_least_twice_of_others.go b/src/0747_largest_number_at_least_twice_of_others/largest_number_at_least_twice_of_others.go new file mode 100644 index 0000000..d374949 --- /dev/null +++ b/src/0747_largest_number_at_least_twice_of_others/largest_number_at_least_twice_of_others.go @@ -0,0 +1,60 @@ +/* +747. Largest Number At Least Twice of Others + +Source: https://leetcode.com/problems/largest-number-at-least-twice-of-others/ + +In a given integer array nums, there is always exactly one largest element. + +Find whether the largest element in the array is at least twice as much as every other number in the array. + +If it is, return the index of the largest element, otherwise return -1. + +Example 1: + +Input: nums = [3, 6, 1, 0] +Output: 1 +Explanation: 6 is the largest integer, and for every other number in the array x, +6 is more than twice as big as x. The index of value 6 is 1, so we return 1. + + +Example 2: + +Input: nums = [1, 2, 3, 4] +Output: -1 +Explanation: 4 isn't at least as big as twice the value of 3, so we return -1. + + +Note: + +1. nums will have a length in the range [1, 50]. +2. Every nums[i] will be an integer in the range [0, 99]. + +*/ +// 2018-12-18 + +package largestnumberatleasttwiceofothers + +import "leetcode/utils" + +// Time complexity: O(n) +// Space complexity: O(1) +func dominantIndex(nums []int) int { + var ( + maxNum = utils.MinInt + res int + ) + + for i, j := range nums { + if j > maxNum { + maxNum = j + res = i + } + } + + for _, j := range nums { + if maxNum < 2*j && j != maxNum { + return -1 + } + } + return res +} diff --git a/src/0747_largest_number_at_least_twice_of_others/largest_number_at_least_twice_of_others_test.go b/src/0747_largest_number_at_least_twice_of_others/largest_number_at_least_twice_of_others_test.go new file mode 100644 index 0000000..0907622 --- /dev/null +++ b/src/0747_largest_number_at_least_twice_of_others/largest_number_at_least_twice_of_others_test.go @@ -0,0 +1,18 @@ +package largestnumberatleasttwiceofothers + +import "testing" + +func TestDominantIndex(t *testing.T) { + testCases := [][]int{ + {0, 0, 0, 1}, + {0, 0, 1, 1}, + {1, 2, 3, 4}, + {3, 6, 1, 0}, + } + expected := []int{3, 2, -1, 1} + for index, data := range testCases { + if res := dominantIndex(data); res != expected[index] { + t.Errorf("expected %d, got %d", expected[index], res) + } + } +} diff --git a/src/README.md b/src/README.md new file mode 100644 index 0000000..f79d207 --- /dev/null +++ b/src/README.md @@ -0,0 +1,44 @@ +### Solution for LeetCode algorithm problems, continually updating. + +|ID|Title && solution|Coefficient of difficulty|remarks| +|:---:|:---:|:---:|:---:| +|0001|[Two Sum](0001_two_sum/twosum.go)|Easy|*`array;`* *`lookup table`*| +|0002|[Add Two Numbers](0002_add_two_numbers/add_two_numbers.go)|Medium|| +|0003|[Longest Substring Without Repeating Characters](0003_longest_substring_without_repeating_characters/longest_substring_without_repeating_characters.go)|Medium|*`sliding window`*| +|0017|[Letter Combinations of a Phone Number](0017_letter_combination_of_a_phone_number/letter_combination_of_phone_number.go)|Medium|*`tree`*| +|0020|[Valid Parentheses](0020_valid_parentheses/valid_parentheses.go)|Easy|| +|0021|[Merge Two Sorted Lists](0021_merge_two_sorted_lists/mergeTwoLists.go)|Easy|| +|0025|[Reverse Nodes in k-Group](./0025_reverse_nodes_in_k_group/reverse_node_k_group.go)|Hard|| +|0061|[Rotate List](./0061_rotate_list/rotate_list.go)|Medium|| +|0062|[Unique Paths](./0062_unique_paths/unique_paths.go)|Medium|*`recursion;`* *`memory search;`* *`dynamic programming`*| +|0063|[Unique Paths 2](./0063_unique_paths_2/unique_paths2.go)|Medium|*`recursion;`* *`memory search;`* *`dynamic programming`*| +|0064|[Minimum Path Sum](./0064_minimum_path_sum/minimum_path_sum.go)|Medium|*`dynamic programming;`* *` dfs`*| +|0067|[add Binary](./0067_add_binary/README.md)|Easy|| +|0070|[Climbing Stairs](./0070_climbing_stairs/climbing_stairs.go)|Easy|*`dynamic programming`*| +|0076|[Minimum Window Substring](./0076_minimum_window_substring/minimum_window_substring.go)|Hard|*`sliding window`*| +|0094|[Binary Tree Inorder Traversal](./0094_binary_tree_inorder_traversal/binary_tree_inorder_traversal.go)|Medium|*`binary tree`*| +|0100|[Same Tree](./0100_same_tree/same_tree.go)|Easy|*`binary tree`*| +|0101|[Symmetric Tree](./0101_symmetric_tree/symmetric_tree.go)|Easy|*`stack;`* *`recursion; `* *`iterative`*| +|0107|[Binary Tree Level Order Traversal II](./0107_binary_tree_level_order_traversal_2/binary_tree_level_order_traversal2.go)|Easy|*`binary tree`*| +|0111|[Minimum Depth of Binary Tree](./0111_minimum_depth_of_binary_tree/minimum_depth_of_binary_tree.go)|Easy|*`binary tree`*| +|0112|[Path Sum](./0112_path_sum/path_sum.go)|Easy|*`binary tree`*| +|0120|[Triangle](./0120_triangle/triangle.go)|Medium|*`dynamic programming;`* *` dfs`*| +|0167|[Two Sum II - Input array is sorted](./0167_two_sum2/two_sum2.go)|Easy|*`对撞指针(双索引)`*| +|0198|[House Robber](./0198_house_robber/house_robber.go)|Easy|*`memory search;`* *`dynamic programming`*| +|0209|[Minimum Size Subarray Sum](./0209_minimum_size_subarray_sum/minimum_size_subarray_sum.go)|Medium|*`sliding window`*| +|0226|[Invert Binary Tree](./0226_invert_binary_tree/invert_binary_tree.go)|Easy|*`recursion; `* *`binary tree`*| +|0283|[Move Zeroes(solution1)](./0283_move_zeroes/move_zeroes.go)
[Move Zeroes(solution2)](./0283_move_zeroes/move_zeroes2.go)|Easy|*`array`*| +|0300|[Longest Increasing Subsequence](./0300_longest_increasing_subsequence/lis.go)|Medium|*`dp`*| +|0343|[Integer Break](./0343_integer_break/integer_break.go)|Medium|*`recursion;`* *`memory search;`* *`dynamic programming`*| +|0349|[Intersection of Two Arrays](./0349_intersection_of_2_arrays/intersection_of_two_arrays.go)|Easy|*`set`*| +|0350| [Intersection of Two Arrays II](./0350_intersection_of_two_arrays2/intersection_of_two_arrays2.go)|Easy|*`map`*| +|0376|[Wiggle Subsequence](./0376_wiggle_subsequence/wiggle_subsequence.go)|Medium|*`dp`*| +|0392|[Is Subsequence](./0392_is_subsequence/is_subsequence.go)|Medium|*`greedy algorithm`*| +|0416|[Partition Equal Subset Sum](./0416_partition_equal_subset_sum/partition_equal_subset_sum.go)|Medium|*`dp;`* *`0-1 knapsack problem`*| +|0435|[Non-overlapping Intervals(dp solution)](./0435_non_overlapping_intervals/dp_solution.go)
[Non-overlapping Intervals(greedy solution)](./0435_non_overlapping_intervals/greedy_solution.go)|Medium|*`dp;`* *`0-1 knapsack problem`*| +|0438|[ Find All Anagrams in a String](./0438_all_anagrams_in_a_string/all_anagrams_in_a_string.go)|Easy|*`sliding window`*| +|0447|[Number of Boomerangs](./0447_number_of_boomerangs/number_of_boomerangs.go)|Easy|| +|0454|[4Sum II](./0454_4sum2/4sum2.go)|Medium|| +|0455|[Assign Cookies](./0455_assign_cookies/assign_cookies.go)|Easy|*`greedy algorithm`*| +|0728|[Self Dividing Numbers](./0728_self_dividing_numbers/self_dividing_numbers.go)|Easy|| +|0747|[Largest Number At Least Twice of Others](./0455_assign_cookies/largest_number_at_least_twice_of_others.go)|Easy|| diff --git a/ut.sh b/ut.sh old mode 100644 new mode 100755