diff --git a/src/content/leetcode-solutions/0003-longest-substring-without-repeating-characters.md b/src/content/leetcode-solutions/0003-longest-substring-without-repeating-characters.md new file mode 100644 index 00000000..c802328a --- /dev/null +++ b/src/content/leetcode-solutions/0003-longest-substring-without-repeating-characters.md @@ -0,0 +1,121 @@ +--- +layout: "../layouts/Post.astro" +title: "3. Longest Substring Without Repeating Characters" +slug: "0003-longest-substring-without-repeating-characters" +keywords: +- "longest" +- "substring" +- "without" +- "repeating" +- "characters" +author: "ansidev" +pubDate: "2022-10-31T19:46:49+07:00" +difficulty: "Medium" +tags: +- "Hash Table" +- "String" +- "Sliding Window" +--- +## Problem + +Given a string `s`, find the length of the **longest substring** without repeating characters. + +**Example 1:** + +``` +Input: s = "abcabcbb" +Output: 3 +Explanation: The answer is "abc", with the length of 3. +``` + +**Example 2:** + +``` +Input: s = "bbbbb" +Output: 1 +Explanation: The answer is "b", with the length of 1. +``` + +**Example 3:** + +``` +Input: s = "pwwkew" +Output: 3 +Explanation: The answer is "wke", with the length of 3. +Notice that the answer must be a substring, "pwke" is a subsequence and not a substring. +``` + +**Constraints:** + +- `0 <= s.length <= 5 * 104` +- `s` consists of English letters, digits, symbols, and spaces. + +## Analysis + +| Abbreviation | Stands for | +| ------------ | ------------------------------------------------ | +| `CSWRC` | `current substring without repeating characters` | +| `LSWRC` | `longest substring without repeating characters` | + +- If `s` is an empty string, the LSWRC is `0`. +- If the length of string `s` is 1, the LSWRC is `1`. + +## Approaches + +### Approach 1 + +#### Approach + +- If the length of string `s` is greater than 1, because we need to determine the LSWRC, while iterating over the string, we have to check whether the character at a specific index is repeating or not. We can consider using a hashmap. + + - Assume the `LSWRC` is `s[0]`. + + | Initial value | Note | + | --------------------- | ---------------------------------------------------------------------- | + | `left = 0` | Left index of the LSWRC | + | `result = 1` | Length of the LSWRC | + | `lastIndex = { a=0 }` | This hashmap saves the last index of a specific character of the array | + + - Start traversing the array from index `1`. For each step: + - Check whether the current character is repeating: `lastIndex` has the key `s[right]`. + - If yes, update `left = lastIndex[s[right]] + 1` if `left < lastIndex[s[right]] + 1`. + - Update the last index of `s[right]` to the current index. + - Calculate the new length of the `CSWRC`. (`right - left + 1`). + - Update `result` if it is less than the new length of the `CSWRC`. + - Finally, return `result`. It is the `LSWRC`. + +#### Solutions + +```go +func lengthOfLongestSubstring(s string) int { + l := len(s) + if l == 0 || l == 1 { + return l + } + + result, left := 1, 0 + lastIndex := map[byte]int{} + lastIndex[s[0]] = 0 + for right := 1; right < l; right++ { + if v, ok := lastIndex[s[right]]; ok { + if left < v+1 { + left = v + 1 + } + } + lastIndex[s[right]] = right + if result < right-left+1 { + result = right - left + 1 + } + } + + return result +} +``` + +#### Complexity + +- Time complexity: `O(n)` because we just traverse the string once. +- Space complexity: + - We use four extra variables `l`, `result`, `left`, `right`, no matter what value will, they will take fixed bytes. So the space complexity is `O(1)`. + - The space complexity of the map `lastIndex` is `O(n)`. + - So the final space complexity is `O(n)`. diff --git a/src/content/leetcode-solutions/0008-string-to-integer-atoi.md b/src/content/leetcode-solutions/0008-string-to-integer-atoi.md new file mode 100644 index 00000000..e85c389d --- /dev/null +++ b/src/content/leetcode-solutions/0008-string-to-integer-atoi.md @@ -0,0 +1,180 @@ +--- +layout: "../layouts/Post.astro" +title: "8. String to Integer (atoi)" +slug: "0008-string-to-integer-atoi" +keywords: +- "string" +- "to" +- "integer" +- "atoi" +author: "ansidev" +pubDate: "2022-10-26T13:11:00+07:00" +difficulty: "Medium" +tags: +- "String" +--- +## Problem + +Implement the `myAtoi(string s)` function, which converts a string to a 32-bit signed integer (similar to C/C++'s `atoi` function). + +The algorithm for `myAtoi(string s)` is as follows: + +1. Read in and ignore any leading whitespace. +2. Check if the next character (if not already at the end of the string) is `'-'` or `'+'`. Read this character in if it is either. This determines if the final result is negative or positive respectively. Assume the result is positive if neither is present. +3. Read in next the characters until the next non-digit character or the end of the input is reached. The rest of the string is ignored. +4. Convert these digits into an integer (i.e. `"123" -> 123`, `"0032" -> 32`). If no digits were read, then the integer is 0. Change the sign as necessary (from step 2). +5. If the integer is out of the 32-bit signed integer range [-231, 231 - 1], then clamp the integer so that it remains in the range. Specifically, integers less than -231 should be clamped to -231, and integers greater than 231-1 should be clamped to 231-1. +Return the integer as the final result. + +**Note:** + +- Only the space character `' '` is considered a whitespace character. +- **Do not ignore** any characters other than the leading whitespace or the rest of the string after the digits. + +**Example 1:** + +``` +Input: s = "42" +Output: 42 +Explanation: The underlined characters are what is read in, the caret is the current reader position. +Step 1: "42" (no characters read because there is no leading whitespace) + ^ +Step 2: "42" (no characters read because there is neither a `'-'` nor `'+'`) + ^ +Step 3: "42" ("42" is read in) + ^ +The parsed integer is 42. +Since 42 is in the range [-2^31, 2^31 - 1], the final result is 42. +``` + +**Example 2:** + +``` +Input: s = " -42" +Output: -42 +Explanation: +Step 1: " -42" (leading whitespace is read and ignored) + ^ +Step 2: " -42" (`'-'` is read, so the result should be negative) + ^ +Step 3: " -42" ("42" is read in) + ^ +The parsed integer is -42. +Since -42 is in the range [-2^31, 2^31 - 1], the final result is -42. +``` + +**Example 3:** + +``` +Input: s = "4193 with words" +Output: 4193 +Explanation: +Step 1: "4193 with words" (no characters read because there is no leading whitespace) + ^ +Step 2: "4193 with words" (no characters read because there is neither a `'-'` nor `'+'`) + ^ +Step 3: "4193 with words" ("4193" is read in; reading stops because the next character is a non-digit) + ^ +The parsed integer is 4193. +Since 4193 is in the range [-2^31, 2^31 - 1], the final result is 4193. +``` + +**Constraints:** + +- `0 <= s.length <= 200`. +- `s` consists of English letters (lower-case and upper-case), digits (`0-9`), `' '`, `'+'`, `'-'`, and `'.'`. + +## Analysis + +I don't have any special analysis since the problem is so clearly. + +## Approaches + +### Approach 1 + +#### Approach + +1. Check whether the input is null (depends on programming language) or empty. If it is, return `0`. +2. Use a pointer `i` to traverse the input string, always remember checking whether i less than length of `s`. + - While `s[i]` is a whitespace, keep increasing i by 1. + - Check whether the next character (`s[i]`) is one of `-`, `+`, or digit (`0-9`): + - If not, return `0`. + - Otherwise, check whether `s[i]` is one of `-` or `+`, save the result to a boolean variable and increase i by 1. + - Note that if `s[i]` is not one of `-` or `+`, this means that it is a digit, and `i` will not be increased. + - Check whether the current character is a sign, if it is, return `0` because it is an invalid input. + - Create new 64 bit float number `n` to save the result. + - While `s[i]` is a digit, `n = n x 10 + integer value of s[i]`, then increasing `i` by `1`. + - If the sign is `-`, `n = -n`. + - Check the range of `n`: + - If n < -231, return -231. + - If n > 231-1, return 231-1. + - Otherwise, convert n to integer and return. + +- Notes: `MinInt32 = -1 << 31` (-231) and `MaxInt32 = 1<<31 - 1` (231-1). + +#### Solutions + +```go +func myAtoi(s string) int { + l := len(s) + if l == 0 { + return 0 + } + + i := 0 + for i < l && s[i] == ' ' { + i++ + } + + if i < l && s[i] != '+' && + s[i] != '-' && + s[i] != '0' && + s[i] != '1' && + s[i] != '2' && + s[i] != '3' && + s[i] != '4' && + s[i] != '5' && + s[i] != '6' && + s[i] != '7' && + s[i] != '8' && + s[i] != '9' { + return 0 + } + + isNegative := false + if i < l && s[i] == '-' { + isNegative = true + i++ + } else if i < l && s[i] == '+' { + i++ + } + + if i < l && (s[i] == '+' || s[i] == '-') { + return 0 + } + + var n float64 = 0 + for i < l && s[i] >= '0' && s[i] <= '9' { + n = n*10 + float64(s[i]-'0') + i++ + } + + if isNegative { + n = -n + } + + if n < math.MinInt32 { + return math.MinInt32 + } + if n > math.MaxInt32 { + return math.MaxInt32 + } + + return int(n) +} +``` + +#### Complexity + +- Time complexity: `O(n)` because we just traverse the string once. +- Space complexity: We use three extra variable `l`, `isNegative`, `n`, no matter what value will, they will take a fixed bytes. So the space complexity is `O(1)`. diff --git a/src/content/leetcode-solutions/0053-maximum-subarray.md b/src/content/leetcode-solutions/0053-maximum-subarray.md new file mode 100644 index 00000000..947cd7fc --- /dev/null +++ b/src/content/leetcode-solutions/0053-maximum-subarray.md @@ -0,0 +1,107 @@ +--- +layout: "../layouts/Post.astro" +title: "53. Maximum Subarray" +slug: "0053-maximum-subarray" +keywords: +- "maximum" +- "subarray" +- "kadane" +author: "ansidev" +pubDate: "2022-10-26T13:11:00+07:00" +difficulty: "Medium" +tags: +- "Array" +- "Divide and Conquer" +- "Dynamic Programming" +--- +## Problem + +Given an integer array `nums`, find the contiguous subarray (containing at least one number) which has the largest sum and return `its sum`. + +A `subarray` is a `contiguous` part of an array. + +**Example 1:** + +``` +Input: nums = [-2,1,-3,4,-1,2,1,-5,4] +Output: 6 +Explanation: [4,-1,2,1] has the largest sum = 6. +``` + +**Example 2:** + +``` +Input: nums = [1] +Output: 1 +``` + +**Example 3:** + +``` +Input: nums = [5,4,-1,7,8] +Output: 23 +``` + +**Constraints:** + +- 1 <= nums.length <= 105 +- -104 <= nums[i] <= 104 + +**Follow up:** If you have figured out the `O(n)` solution, try coding another solution using the **divide and conquer** approach, which is more subtle. + +## Analysis + +## Approaches + +### Approach 1 + +#### Approach + +Technique: Dynamic Programming + +Original author: [Kadane](https://www.cmu.edu/dietrich/statistics-datascience/people/faculty/joseph-kadane.html). + +Assume we have `dp[i]`: maximum sum of subarray that ends at index `i`. + +`dp[i] = max(dp[i - 1] + nums[i], nums[i])` + +Initial state `dp[0] = nums[0]`. + +From the above formula, we just need to access its previous element at each step, so we can use 2 variables: + +- `currentMaxSum`: maximum sum of subarray that ends at the current index `i`. + - `currentMaxSum = max(currentMaxSum + nums[i], nums[i]`. +- `globalSum`: global maximum subarray sum + - `globalSum = max(currentMaxSum, globalSum)`. + +#### Solutions + +```go +func maxSubArray(nums []int) int { + currentMaxSum := nums[0] + globalSum := nums[0] + + for _, x := range nums[1:] { + if currentMaxSum+x > x { + currentMaxSum += x + } else { + currentMaxSum = x + } + + if globalSum < currentMaxSum { + globalSum = currentMaxSum + } + } + + return globalSum +} +``` + +#### Complexity + +- **Time Complexity**: `O(n)` because we just iterate over the array once. +- **Space Complexity**: `O(1)`. We just use 2 integer variables for extra spaces. + +## References + +- https://en.wikipedia.org/wiki/Maximum_subarray_problem diff --git a/src/content/leetcode-solutions/0231-power-of-two.md b/src/content/leetcode-solutions/0231-power-of-two.md new file mode 100644 index 00000000..789584a3 --- /dev/null +++ b/src/content/leetcode-solutions/0231-power-of-two.md @@ -0,0 +1,153 @@ +--- +layout: "../layouts/Post.astro" +title: "231. Power of Two" +slug: "0231-power-of-two" +keywords: +- "power of two" +author: "ansidev" +pubDate: "2022-10-27T15:23:12+07:00" +difficulty: "Easy" +tags: +- "Math" +- "Bit Manipulation" +- "Recursion" +--- +## Problem + +Given an integer `n`, return `true` *if it is a power of two. Otherwise, return* `false`. + +An integer `n` is a power of two, if there exists an integer `x` such that n == 2x. + +**Example 1:** + +``` +Input: n = 1 +Output: true +Explanation: 20 = 1 +``` +**Example 2:** + +``` +Input: n = 16 +Output: true +Explanation: 24 = 16 +``` +**Example 3:** + +``` +Input: n = 3 +Output: false +``` + +**Constraints:** + +- -231 <= n <= 231 - 1. + +**Follow up:** Could you solve it without loops/recursion? + +## Analysis + +1. If `n` is a power of two: + +
+n = 2i (`i ≥ 0`)
+  ≥ 20 = 1
+
+ +`=>` **If `n < 0`, `n` is not a power of two**. + +2. If `n` is a power of two: + +The binary form of every 2i (`i` is a non-negative number): + +
+2010 = 110 = 12
+
+2110 = 210 = 102
+
+2210 = 410 = 1002
+
+2310 = 810 = 10002
+
+...
+
+2i10 = 100...002 (only one 1-digit at the first position and followed by total `i` 0-digit numbers)
+       |__i__|
+
+ +2.1. If `i = 0`: +
+n = 20 = 1 > 0
+n & (n-1) = 1 & 0 = 0
+
+ + +2.2. If `i > 0`: + +The binary form of every 2i - 1: + +
+2110 - 1 = 110 = 012
+
+2210 - 1 = 310 = 0112
+
+2310 - 1 = 710 = 01112
+
+...
+
+2i10 - 1 = 011...112 (total `i` 1-digit numbers)
+           |__i__|
+
+ +For `i > 0`, we have: + +
+n - 1 = 2i10 - 1 ≥ 0
+n & (n-1) = 2i10 & 2i10 - 1 = 100...002 & 011...112 = 0
+                 |__i__|     |__i__|
+
+ +``` +If n is a power of two: n & (n-1) = 0. +``` + +3. If `n` is not an power of two, we have: +
+             n10 = [0....0][1....1][0....0]2 (i ≥ 0, j ≥ 2, k ≥ 1)
+                   |__i__| |__j__| |__k__|
+
+         (n-1)10 = [0....0][1....1]0[1....1]2
+                   |__i__| |_j-1_|  |__k__|
+
+x = n10 & (n-1)10 = [0....0][1.....][0....0]2
+                   |__i__| |_j-1_| |_k+1_|
+
+ +- `j ≥ 2` => `j-1 ≥ 1`. So `x` has at least one 1-digit number => `x > 0`. + +``` +If n is not a power of two: n & (n-1) > 0. +``` + +``` +As result, n is a power of two if and only if n > 0 and n & (n-1) = 0. +``` +## Approaches + +### Approach 1 + +#### Approach + +- `n` is a power of two if and only if `n > 0` and `n & (n-1) = 0`. + +#### Solutions + +```go +func isPowerOfTwo(n int) bool { + return n > 0 && n&(n-1) == 0 +} +``` + +#### Complexity + +- **Time Complexity**: `O(1)`. diff --git a/src/content/leetcode-solutions/0628-maximum-product-of-three-numbers.md b/src/content/leetcode-solutions/0628-maximum-product-of-three-numbers.md new file mode 100644 index 00000000..79cd737f --- /dev/null +++ b/src/content/leetcode-solutions/0628-maximum-product-of-three-numbers.md @@ -0,0 +1,143 @@ +--- +layout: "../layouts/Post.astro" +title: "628. Maximum Product of Three Numbers" +slug: "0628-maximum-product-of-three-numbers" +keywords: +- "maximum" +- "product" +- "of" +- "three" +- "numbers" +author: "ansidev" +pubDate: "2022-11-18T08:58:46+07:00" +difficulty: "Easy" +tags: +- "Array" +- "Math" +- "Sorting" +--- +## Problem + +Given an integer array `nums`, *find three numbers whose product is maximum and return the maximum product*. + +**Example 1:** + +``` +Input: nums = [1,2,3] +Output: 6 +``` + +**Example 2:** + +``` +Input: nums = [1,2,3,4] +Output: 24 +``` + +**Example 3:** + +``` +Input: nums = [-1,-2,-3] +Output: -6 + ``` + +**Constraints:** + +- `3 <= nums.length <= 104`. +- `-1000 <= nums[i] <= 1000`. + +## Analysis + +If length of `nums` is 3, maximum product is `nums[0] x nums[1] x nums[2]`. + +## Approaches + +### Approach 1 + +``` +Notes: +- l: length of nums. +- nums[i:j]: sub array of nums from index i to j (includes nums[i], nums[j]). +``` +#### Approach + +- If length of `nums` is 3, maximum product is `nums[0] x nums[1] x nums[2]`. +- If length of `nums` is greater than 3: + - Step 1: Sort the input array (ascending). + - For the sorted array, there are following possible cases: + - Case 1: All element are positive numbers. + - `maxProduct = nums[l-3] x nums[l-2] x nums[l-1]`. + - Case 2: All element are negative numbers. + - Product of two random elements will be a positive number. + - Product of three random elements will be a negative number. + - If `n1 > 0`, `n2 < n3 < 0`: `n1 x n2 < n1 x n3 < 0`. + - If `m1 < 0`, `0 < m2 < n3`: `m1 x m3 < m1 x m2 < 0`. + - So to find the maximum product of three numbers in this case, we need to find two negative numbers `a`, `b` that `a x b` has max value (note that `a x b > 0`), then find the third number which is the maximum value of remaining ones. + - `nums[0]` & `nums[1]` are two smallest negative numbers. So their product will be the maximum product of two numbers. `nums[l-1]` is the maximum one of [`nums[2]`, `nums[3]`,..., `nums[l-1]`]. + - Finally, the maximum product of three numbers in this case is 👉 `nums[0] x nums[1] x nums[l-1]`. + - Other cases. + - `nums` has at least 4 elements. + - If `nums` contains zero: + - If `nums[0] = 0`, all remaining elements are positive numbers (similar to case 1) + - 👉 `maxProduct = nums[l-3] x nums[l-2] x nums[l-1]`. + - If `nums[l-1] = 0`, all remaining elements are negative numbers (similar to case 2) + - `maxProduct` of three numbers of sub array `nums[0:l-2]` is a negative number, it less than product of `nums[l-1]` (`= 0`) and two random numbers of sub array `nums[0:l-2]`. So in this case, we can pick three numbers `nums[l-3]`, `nums[l-2]`, `nums[l-1]`. + - 👉 `maxProduct = nums[l-3] x nums[l-2] x nums[l-1] = 0`. + - If `nums[i] = 0` (`0 < i < l-1`), because `nums` has at least 4 elements, so there are possible cases: + - `nums` has at least there positive numbers, similar to case 1. + - `nums` has two positive numbers: + - If `l = 4`: + - `nums` = [`nums[0]`, `0`, `num[2]`, `nums[3]`]. + - `nums[0] x nums[2] x nums[3] < 0 x num[2] x nums[3] = 0`. + - 👉 `maxProduct` must contains zero so `maxProduct = 0 = nums[l-3] x nums[l-2] x nums[l-1]` + - If `l > 4`: + - `nums` = [`nums[0]`, `nums[1]`, ..., `nums[l-4]` ,`0`, `num[l-2]`, `nums[l-1]`]. + - If one of three numbers of `maxProduct` is zero, `maxProduct = 0`. + - Otherwise, if two of three numbers of `maxProduct` is `num[l-2]`, `nums[l-1]`, `maxProduct < 0`. + - Otherwise, two of three numbers of `maxProduct` is negative numbers, max product of two negative numbers of sub array `nums[0:l-4]` is `nums[0] x nums[1] > 0`. + - `maxProduct = nums[0] x nums[1] x nums[l-1] > 0` + - 👉 `maxProduct = nums[0] x nums[1] x nums[l-1] > 0` + - 👉 `maxProduct = nums[0] x nums[1] x nums[l-1]` + - `nums` has one positive numbers: + - `nums` = [`nums[0]`, `nums[1]`, ..., `nums[l-3]` ,`0`, `nums[l-1]`]. + - We have cases: + - `maxProduct` contains zero: `0 x nums[i] x nums[j] = 0` + - `maxProduct` does not contain zero: + - `nums[i] x nums[j] x nums[k] < 0` (`i < j < k < 0`) + - `nums[i] x nums[j] x nums[l-1] > 0` (`i < j < 0`) + - So `maxProduct` is product of two negative numbers and one positive number (`nums[l-1]`) + - 👉 `maxProduct = max(nums[j] x num[j]) x nums[l-1] = nums[0] x nums[1] x nums[l-1]`. + - The maximum product of three numbers in every cases (`l > 3`) is one of two: + - `nums[0] x nums[1] x nums[l-1]` + - `nums[l-3] x nums[l-2] x nums[l-1]` + - Conclusion, 👉 `maxProduct = max(nums[0] x nums[1] x nums[l-1], nums[l-3] x nums[l-2] x nums[l-1])`. + +#### Solutions + +```go +import "sort" + +func maximumProduct(nums []int) int { + l := len(nums) + + if l == 3 { + return nums[0] * nums[1] * nums[2] + } + + sort.Ints(nums) + + return max(nums[0]*nums[1]*nums[l-1], nums[l-3]*nums[l-2]*nums[l-1]) +} + +func max(x int, y int) int { + if x > y { + return x + } + + return y +} +``` + +#### Complexity + +- **Time Complexity**: Time complexity of the sort algorithm. diff --git a/src/content/leetcode-solutions/2400-number-of-ways-to-reach-a-position-after-exactly-k-steps.md b/src/content/leetcode-solutions/2400-number-of-ways-to-reach-a-position-after-exactly-k-steps.md new file mode 100644 index 00000000..f57b4743 --- /dev/null +++ b/src/content/leetcode-solutions/2400-number-of-ways-to-reach-a-position-after-exactly-k-steps.md @@ -0,0 +1,120 @@ +--- +layout: "../layouts/Post.astro" +title: "2400. Number of Ways to Reach a Position After Exactly k Steps" +slug: "2400-number-of-ways-to-reach-a-position-after-exactly-k-steps" +keywords: +- "number" +- "of" +- "ways" +- "to" +- "reach" +- "a" +- "position" +- "after" +- "exactly" +- "k" +- "steps" +author: "ansidev" +pubDate: "2022-10-24T23:49:00+07:00" +difficulty: "Medium" +tags: +- "Math" +- "Dynamic Programming" +- "Combinatorics" +--- +## Problem + +You are given two **positive** integers `startPos` and `endPos`. Initially, you are standing at position startPos on an **infinite** number line. With one step, you can move either one position to the left, or one position to the right. + +Given a positive integer `k`, return the number of **different** ways to reach the position `endPos` starting from `startPos`, such that you perform **exactly** `k` steps. Since the answer may be very large, return it **modulo** 109 + 7. + +Two ways are considered different if the order of the steps made is not exactly the same. + +**Note** that the number line includes negative integers. + +**Example 1:** + +``` +Input: startPos = 1, endPos = 2, k = 3 +Output: 3 +Explanation: We can reach position 2 from 1 in exactly 3 steps in three ways: +- 1 -> 2 -> 3 -> 2. +- 1 -> 2 -> 1 -> 2. +- 1 -> 0 -> 1 -> 2. +It can be proven that no other way is possible, so we return 3. +``` +**Example 2:** + +``` +Input: startPos = 2, endPos = 5, k = 10 +Output: 0 +Explanation: It is impossible to reach position 5 from position 2 in exactly 10 steps. +``` + +**Constraints:** + +- `1 <= startPos, endPos, k <= 1000` + +## Analysis + +Assuming `d` is the **distance** between `startPos` and `endPos` => `d = abs(startPos - endPos)`. + +- `1 <= startPos <= 1000` +- `-1000 <= -endPos <= -1` + +=> `-999 <= startPos - endPos <= 999` + +=> `0 <= d = abs(startPos - endPos) <= 999` + +For `k` is the **numbers of steps** and `d` is the **distance** between `startPos` and `endPos`, the number of ways is: +- `dfs(k, d) = dfs(k-1, abs(d-1)) + dfs(k-1, d+1)`. + +For k steps, the maximum distance is k. +- **d > k**: `dfs(k, d) = 0`. +- **d = k**: `dfs(k, d) = dfs(k, k) = 1`. +- **d = 0**: `dfs(k, 0) = dfs(k-1, 1) + dfs(k-1, 1) = 2 x dfs(k-1, 1)`. + + +Example values: +- `dfs(0,0) = 1`. +- `dfs(1, 0) = 2 x dfs(0, 1) = 0`. +- `dfs(1, 1) = 1`. +- `dfs(2, 0) = 2 x dfs(1, 1) = 2 x 1 = 2`. +- `dfs(2, 1) = dfs(1, 0) + dfs(1, 2) = 0 + 0 = 0`. +- `dfs(2, 2) = 1`. + +## Approaches + +### Approach 1 + +#### Approach + +- From the above analysis, we can use the bottom-up approach to calculate the next values of the `dfs` function from each prior values. Then, we can get the number of ways. + +#### Solutions + +```go +func numberOfWays(startPos int, endPos int, k int) int { + const mod = 1e9 + 7 + dp := [1001][1001]int{} + for i := 1; i <= 1000; i++ { + dp[i][i] = 1 + for j := 0; j < i; j++ { + dp[i][j] = (dp[i-1][abs(j-1)] + dp[i-1][j+1]) % mod + } + } + + return dp[k][abs(startPos-endPos)] +} + +func abs(x int) int { + if x >= 0 { + return x + } + + return -x +} +``` + +## References +- dfs: [[deep-first-search|Deep First Search]]