From e23638b42807989b813f74b4bd5ca8cb84093e84 Mon Sep 17 00:00:00 2001 From: Yang Libin Date: Wed, 6 Sep 2023 02:34:01 +0000 Subject: [PATCH] feat: add solutions to lc problems: No.1207,1214 * No.1207.Unique Number of Occurrences * No.1214.Two Sum BSTs --- .github/workflows/compress.yml | 6 +- .../1195.Fizz Buzz Multithreaded/README.md | 59 ++++++ .../1195.Fizz Buzz Multithreaded/README_EN.md | 120 +++++++++++ .../README.md | 12 ++ .../README_EN.md | 12 ++ .../Solution.ts | 7 + .../1200-1299/1214.Two Sum BSTs/README.md | 187 ++++++++++++------ .../1200-1299/1214.Two Sum BSTs/README_EN.md | 175 ++++++++++------ .../1200-1299/1214.Two Sum BSTs/Solution.cpp | 36 ++-- .../1200-1299/1214.Two Sum BSTs/Solution.go | 33 ++-- .../1200-1299/1214.Two Sum BSTs/Solution.java | 30 +-- .../1200-1299/1214.Two Sum BSTs/Solution.py | 32 +-- .../1200-1299/1214.Two Sum BSTs/Solution.ts | 43 ++++ 13 files changed, 564 insertions(+), 188 deletions(-) create mode 100644 solution/1200-1299/1207.Unique Number of Occurrences/Solution.ts create mode 100644 solution/1200-1299/1214.Two Sum BSTs/Solution.ts diff --git a/.github/workflows/compress.yml b/.github/workflows/compress.yml index 10a3e3012e3c9..e77f6e8ca9f05 100644 --- a/.github/workflows/compress.yml +++ b/.github/workflows/compress.yml @@ -34,7 +34,7 @@ jobs: id: calibre uses: calibreapp/image-actions@main with: - githubToken: ${{ secrets.ACTION_TOKEN }} + githubToken: ${{ secrets.GITHUB_TOKEN }} # For non-Pull Requests, run in compressOnly mode and we'll PR after. compressOnly: ${{ github.event_name != 'pull_request' }} - name: Create Pull Request @@ -44,7 +44,7 @@ jobs: steps.calibre.outputs.markdown != '' uses: peter-evans/create-pull-request@v4 with: - title: Auto Compress Images + title: 'chore: auto compress images' branch-suffix: timestamp - commit-message: Compress Images + commit-message: 'chore: auto compress images' body: ${{ steps.calibre.outputs.markdown }} \ No newline at end of file diff --git a/solution/1100-1199/1195.Fizz Buzz Multithreaded/README.md b/solution/1100-1199/1195.Fizz Buzz Multithreaded/README.md index 3606cadfc0635..1635dbef80211 100644 --- a/solution/1100-1199/1195.Fizz Buzz Multithreaded/README.md +++ b/solution/1100-1199/1195.Fizz Buzz Multithreaded/README.md @@ -65,7 +65,66 @@ class FizzBuzz { ```java +class FizzBuzz { + private int n; + + public FizzBuzz(int n) { + this.n = n; + } + private Semaphore fSema = new Semaphore(0); + private Semaphore bSema = new Semaphore(0); + private Semaphore fbSema = new Semaphore(0); + private Semaphore nSema = new Semaphore(1); + + // printFizz.run() outputs "fizz". + public void fizz(Runnable printFizz) throws InterruptedException { + for (int i = 3; i <= n; i = i + 3) { + if (i % 5 != 0) { + fSema.acquire(); + printFizz.run(); + nSema.release(); + } + } + } + + // printBuzz.run() outputs "buzz". + public void buzz(Runnable printBuzz) throws InterruptedException { + for (int i = 5; i <= n; i = i + 5) { + if (i % 3 != 0) { + bSema.acquire(); + printBuzz.run(); + nSema.release(); + } + } + } + + // printFizzBuzz.run() outputs "fizzbuzz". + public void fizzbuzz(Runnable printFizzBuzz) throws InterruptedException { + for (int i = 15; i <= n; i = i + 15) { + fbSema.acquire(); + printFizzBuzz.run(); + nSema.release(); + } + } + + // printNumber.accept(x) outputs "x", where x is an integer. + public void number(IntConsumer printNumber) throws InterruptedException { + for (int i = 1; i <= n; i++) { + nSema.acquire(); + if (i % 3 == 0 && i % 5 == 0) { + fbSema.release(); + } else if (i % 3 == 0) { + fSema.release(); + } else if (i % 5 == 0) { + bSema.release(); + } else { + printNumber.accept(i); + nSema.release(); + } + } + } +} ``` ### **C++** diff --git a/solution/1100-1199/1195.Fizz Buzz Multithreaded/README_EN.md b/solution/1100-1199/1195.Fizz Buzz Multithreaded/README_EN.md index 4a3b3eae3075f..49c03622058e7 100644 --- a/solution/1100-1199/1195.Fizz Buzz Multithreaded/README_EN.md +++ b/solution/1100-1199/1195.Fizz Buzz Multithreaded/README_EN.md @@ -69,7 +69,127 @@ ### **Java** ```java +class FizzBuzz { + private int n; + + public FizzBuzz(int n) { + this.n = n; + } + + private Semaphore fSema = new Semaphore(0); + private Semaphore bSema = new Semaphore(0); + private Semaphore fbSema = new Semaphore(0); + private Semaphore nSema = new Semaphore(1); + + // printFizz.run() outputs "fizz". + public void fizz(Runnable printFizz) throws InterruptedException { + for (int i = 3; i <= n; i = i + 3) { + if (i % 5 != 0) { + fSema.acquire(); + printFizz.run(); + nSema.release(); + } + } + } + + // printBuzz.run() outputs "buzz". + public void buzz(Runnable printBuzz) throws InterruptedException { + for (int i = 5; i <= n; i = i + 5) { + if (i % 3 != 0) { + bSema.acquire(); + printBuzz.run(); + nSema.release(); + } + } + } + + // printFizzBuzz.run() outputs "fizzbuzz". + public void fizzbuzz(Runnable printFizzBuzz) throws InterruptedException { + for (int i = 15; i <= n; i = i + 15) { + fbSema.acquire(); + printFizzBuzz.run(); + nSema.release(); + } + } + + // printNumber.accept(x) outputs "x", where x is an integer. + public void number(IntConsumer printNumber) throws InterruptedException { + for (int i = 1; i <= n; i++) { + nSema.acquire(); + if (i % 3 == 0 && i % 5 == 0) { + fbSema.release(); + } else if (i % 3 == 0) { + fSema.release(); + } else if (i % 5 == 0) { + bSema.release(); + } else { + printNumber.accept(i); + nSema.release(); + } + } + } +} +``` +### **C++** + +```cpp +class FizzBuzz { +private: + std::mutex mtx; + atomic index; + int n; + +public: + FizzBuzz(int n) { + this->n = n; + index = 1; + } + + // printFizz() outputs "fizz". + void fizz(function printFizz) { + while (index <= n) { + std::lock_guard lk(mtx); + if (0 == index % 3 && 0 != index % 5 && index <= n) { + printFizz(); + index++; + } + } + } + + // printBuzz() outputs "buzz". + void buzz(function printBuzz) { + while (index <= n) { + std::lock_guard lk(mtx); + if (0 == index % 5 && 0 != index % 3 && index <= n) { + printBuzz(); + index++; + } + } + } + + // printFizzBuzz() outputs "fizzbuzz". + void fizzbuzz(function printFizzBuzz) { + while (index <= n) { + std::lock_guard lk(mtx); + if (0 == index % 15 && index <= n) { + printFizzBuzz(); + index++; + } + } + } + + // printNumber(x) outputs "x", where x is an integer. + void number(function printNumber) { + while (index <= n) { + std::lock_guard lk(mtx); + if (0 != index % 3 && 0 != index % 5 && index <= n) { + printNumber(index); + index++; + } + } + } +}; ``` ### **...** diff --git a/solution/1200-1299/1207.Unique Number of Occurrences/README.md b/solution/1200-1299/1207.Unique Number of Occurrences/README.md index 5af4ee621cb28..75872d78654f5 100644 --- a/solution/1200-1299/1207.Unique Number of Occurrences/README.md +++ b/solution/1200-1299/1207.Unique Number of Occurrences/README.md @@ -119,6 +119,18 @@ func uniqueOccurrences(arr []int) bool { } ``` +### **TypeScript** + +```ts +function uniqueOccurrences(arr: number[]): boolean { + const cnt: Map = new Map(); + for (const x of arr) { + cnt.set(x, (cnt.get(x) || 0) + 1); + } + return cnt.size === new Set(cnt.values()).size; +} +``` + ### **...** ``` diff --git a/solution/1200-1299/1207.Unique Number of Occurrences/README_EN.md b/solution/1200-1299/1207.Unique Number of Occurrences/README_EN.md index d7ea23f5b66c7..66e943f10bb65 100644 --- a/solution/1200-1299/1207.Unique Number of Occurrences/README_EN.md +++ b/solution/1200-1299/1207.Unique Number of Occurrences/README_EN.md @@ -104,6 +104,18 @@ func uniqueOccurrences(arr []int) bool { } ``` +### **TypeScript** + +```ts +function uniqueOccurrences(arr: number[]): boolean { + const cnt: Map = new Map(); + for (const x of arr) { + cnt.set(x, (cnt.get(x) || 0) + 1); + } + return cnt.size === new Set(cnt.values()).size; +} +``` + ### **...** ``` diff --git a/solution/1200-1299/1207.Unique Number of Occurrences/Solution.ts b/solution/1200-1299/1207.Unique Number of Occurrences/Solution.ts new file mode 100644 index 0000000000000..eb8694a284cfe --- /dev/null +++ b/solution/1200-1299/1207.Unique Number of Occurrences/Solution.ts @@ -0,0 +1,7 @@ +function uniqueOccurrences(arr: number[]): boolean { + const cnt: Map = new Map(); + for (const x of arr) { + cnt.set(x, (cnt.get(x) || 0) + 1); + } + return cnt.size === new Set(cnt.values()).size; +} diff --git a/solution/1200-1299/1214.Two Sum BSTs/README.md b/solution/1200-1299/1214.Two Sum BSTs/README.md index ff337cb6390b7..d688bbbb50269 100644 --- a/solution/1200-1299/1214.Two Sum BSTs/README.md +++ b/solution/1200-1299/1214.Two Sum BSTs/README.md @@ -43,9 +43,15 @@ -先中序遍历二叉搜索树 root1、root2 得到两个有序列表 vals1、vals2。然后利用双指针,i 指向 vals1 头部,j 指向 vals2 尾部,判断双指针指向的两元素和 s 与 target 的大小关系,若相等,直接返回 true,若 `s < target`,i 指针往右移动,否则 j 指针往左移动。 +**方法一:中序遍历 + 双指针** -遍历结束,说明不存在两节点和为 target 的元素,直接返回 false。 +我们分别对两棵树进行中序遍历,得到两个有序数组 $nums[0]$ 和 $nums[1]$,然后使用双指针的方法判断是否存在两个数的和为目标值。双指针判断方法如下: + +初始化两个指针 $i$ 和 $j$,分别指向数组 $nums[0]$ 的左边界和数组 $nums[1]$ 的右边界; + +每次比较 $x = nums[0][i] + nums[1][j]$ 与目标值的大小。如果 $x = target$,则返回 `true`;否则,如果 $x \lt target$,则 $i$ 右移一位;否则,如果 $x \gt target$,则 $j$ 左移一位。 + +时间复杂度 $O(m + n)$,空间复杂度 $O(m + n)$。其中 $m$ 和 $n$ 分别为两棵树的节点数。 @@ -61,23 +67,25 @@ # self.left = left # self.right = right class Solution: - def twoSumBSTs(self, root1: TreeNode, root2: TreeNode, target: int) -> bool: - vals1, vals2 = [], [] - - def inorder(root, vals): - if root: - inorder(root.left, vals) - vals.append(root.val) - inorder(root.right, vals) - - inorder(root1, vals1) - inorder(root2, vals2) - - i, j = 0, len(vals2) - 1 - while i < len(vals1) and j >= 0: - if vals1[i] + vals2[j] == target: + def twoSumBSTs( + self, root1: Optional[TreeNode], root2: Optional[TreeNode], target: int + ) -> bool: + def dfs(root: Optional[TreeNode], i: int): + if root is None: + return + dfs(root.left, i) + nums[i].append(root.val) + dfs(root.right, i) + + nums = [[], []] + dfs(root1, 0) + dfs(root2, 1) + i, j = 0, len(nums[1]) - 1 + while i < len(nums[0]) and ~j: + x = nums[0][i] + nums[1][j] + if x == target: return True - if vals1[i] + vals2[j] < target: + if x < target: i += 1 else: j -= 1 @@ -105,18 +113,19 @@ class Solution: * } */ class Solution { + private List[] nums = new List[2]; + public boolean twoSumBSTs(TreeNode root1, TreeNode root2, int target) { - List vals1 = new ArrayList<>(); - List vals2 = new ArrayList<>(); - inorder(root1, vals1); - inorder(root2, vals2); - int i = 0, j = vals2.size() - 1; - while (i < vals1.size() && j >= 0) { - int s = vals1.get(i) + vals2.get(j); - if (s == target) { + Arrays.setAll(nums, k -> new ArrayList<>()); + dfs(root1, 0); + dfs(root2, 1); + int i = 0, j = nums[1].size() - 1; + while (i < nums[0].size() && j >= 0) { + int x = nums[0].get(i) + nums[1].get(j); + if (x == target) { return true; } - if (s < target) { + if (x < target) { ++i; } else { --j; @@ -125,12 +134,13 @@ class Solution { return false; } - private void inorder(TreeNode root, List vals) { - if (root != null) { - inorder(root.left, vals); - vals.add(root.val); - inorder(root.right, vals); + private void dfs(TreeNode root, int i) { + if (root == null) { + return; } + dfs(root.left, i); + nums[i].add(root.val); + dfs(root.right, i); } } ``` @@ -152,29 +162,31 @@ class Solution { class Solution { public: bool twoSumBSTs(TreeNode* root1, TreeNode* root2, int target) { - vector vals1, vals2; - inorder(root1, vals1); - inorder(root2, vals2); - int i = 0, j = vals2.size() - 1; - while (i < vals1.size() && j >= 0) { - int s = vals1[i] + vals2[j]; - if (s == target) + vector nums[2]; + function dfs = [&](TreeNode* root, int i) { + if (!root) { + return; + } + dfs(root->left, i); + nums[i].push_back(root->val); + dfs(root->right, i); + }; + dfs(root1, 0); + dfs(root2, 1); + int i = 0, j = nums[1].size() - 1; + while (i < nums[0].size() && j >= 0) { + int x = nums[0][i] + nums[1][j]; + if (x == target) { return true; - if (s < target) + } + if (x < target) { ++i; - else + } else { --j; + } } return false; } - - void inorder(TreeNode* root, vector& vals) { - if (root) { - inorder(root->left, vals); - vals.push_back(root->val); - inorder(root->right, vals); - } - } }; ``` @@ -190,15 +202,25 @@ public: * } */ func twoSumBSTs(root1 *TreeNode, root2 *TreeNode, target int) bool { - vals1 := inorder(root1) - vals2 := inorder(root2) - i, j := 0, len(vals2)-1 - for i < len(vals1) && j >= 0 { - s := vals1[i] + vals2[j] - if s == target { + nums := [2][]int{} + var dfs func(*TreeNode, int) + dfs = func(root *TreeNode, i int) { + if root == nil { + return + } + dfs(root.Left, i) + nums[i] = append(nums[i], root.Val) + dfs(root.Right, i) + } + dfs(root1, 0) + dfs(root2, 1) + i, j := 0, len(nums[1])-1 + for i < len(nums[0]) && j >= 0 { + x := nums[0][i] + nums[1][j] + if x == target { return true } - if s < target { + if x < target { i++ } else { j-- @@ -206,14 +228,53 @@ func twoSumBSTs(root1 *TreeNode, root2 *TreeNode, target int) bool { } return false } +``` -func inorder(root *TreeNode) []int { - if root == nil { - return nil - } - left := inorder(root.Left) - right := inorder(root.Right) - return append(append(left, root.Val), right...) +### **TypeScript** + +```ts +/** + * Definition for a binary tree node. + * class TreeNode { + * val: number + * left: TreeNode | null + * right: TreeNode | null + * constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + * } + */ + +function twoSumBSTs(root1: TreeNode | null, root2: TreeNode | null, target: number): boolean { + const nums: number[][] = Array(2) + .fill(0) + .map(() => []); + const dfs = (root: TreeNode | null, i: number) => { + if (!root) { + return; + } + dfs(root.left, i); + nums[i].push(root.val); + dfs(root.right, i); + }; + dfs(root1, 0); + dfs(root2, 1); + let i = 0; + let j = nums[1].length - 1; + while (i < nums[0].length && j >= 0) { + const x = nums[0][i] + nums[1][j]; + if (x === target) { + return true; + } + if (x < target) { + ++i; + } else { + --j; + } + } + return false; } ``` diff --git a/solution/1200-1299/1214.Two Sum BSTs/README_EN.md b/solution/1200-1299/1214.Two Sum BSTs/README_EN.md index 7831069968d80..cace60c6e4c1d 100644 --- a/solution/1200-1299/1214.Two Sum BSTs/README_EN.md +++ b/solution/1200-1299/1214.Two Sum BSTs/README_EN.md @@ -44,23 +44,25 @@ # self.left = left # self.right = right class Solution: - def twoSumBSTs(self, root1: TreeNode, root2: TreeNode, target: int) -> bool: - vals1, vals2 = [], [] + def twoSumBSTs( + self, root1: Optional[TreeNode], root2: Optional[TreeNode], target: int + ) -> bool: + def dfs(root: Optional[TreeNode], i: int): + if root is None: + return + dfs(root.left, i) + nums[i].append(root.val) + dfs(root.right, i) - def inorder(root, vals): - if root: - inorder(root.left, vals) - vals.append(root.val) - inorder(root.right, vals) - - inorder(root1, vals1) - inorder(root2, vals2) - - i, j = 0, len(vals2) - 1 - while i < len(vals1) and j >= 0: - if vals1[i] + vals2[j] == target: + nums = [[], []] + dfs(root1, 0) + dfs(root2, 1) + i, j = 0, len(nums[1]) - 1 + while i < len(nums[0]) and ~j: + x = nums[0][i] + nums[1][j] + if x == target: return True - if vals1[i] + vals2[j] < target: + if x < target: i += 1 else: j -= 1 @@ -86,18 +88,19 @@ class Solution: * } */ class Solution { + private List[] nums = new List[2]; + public boolean twoSumBSTs(TreeNode root1, TreeNode root2, int target) { - List vals1 = new ArrayList<>(); - List vals2 = new ArrayList<>(); - inorder(root1, vals1); - inorder(root2, vals2); - int i = 0, j = vals2.size() - 1; - while (i < vals1.size() && j >= 0) { - int s = vals1.get(i) + vals2.get(j); - if (s == target) { + Arrays.setAll(nums, k -> new ArrayList<>()); + dfs(root1, 0); + dfs(root2, 1); + int i = 0, j = nums[1].size() - 1; + while (i < nums[0].size() && j >= 0) { + int x = nums[0].get(i) + nums[1].get(j); + if (x == target) { return true; } - if (s < target) { + if (x < target) { ++i; } else { --j; @@ -106,12 +109,13 @@ class Solution { return false; } - private void inorder(TreeNode root, List vals) { - if (root != null) { - inorder(root.left, vals); - vals.add(root.val); - inorder(root.right, vals); + private void dfs(TreeNode root, int i) { + if (root == null) { + return; } + dfs(root.left, i); + nums[i].add(root.val); + dfs(root.right, i); } } ``` @@ -133,29 +137,31 @@ class Solution { class Solution { public: bool twoSumBSTs(TreeNode* root1, TreeNode* root2, int target) { - vector vals1, vals2; - inorder(root1, vals1); - inorder(root2, vals2); - int i = 0, j = vals2.size() - 1; - while (i < vals1.size() && j >= 0) { - int s = vals1[i] + vals2[j]; - if (s == target) + vector nums[2]; + function dfs = [&](TreeNode* root, int i) { + if (!root) { + return; + } + dfs(root->left, i); + nums[i].push_back(root->val); + dfs(root->right, i); + }; + dfs(root1, 0); + dfs(root2, 1); + int i = 0, j = nums[1].size() - 1; + while (i < nums[0].size() && j >= 0) { + int x = nums[0][i] + nums[1][j]; + if (x == target) { return true; - if (s < target) + } + if (x < target) { ++i; - else + } else { --j; + } } return false; } - - void inorder(TreeNode* root, vector& vals) { - if (root) { - inorder(root->left, vals); - vals.push_back(root->val); - inorder(root->right, vals); - } - } }; ``` @@ -171,15 +177,25 @@ public: * } */ func twoSumBSTs(root1 *TreeNode, root2 *TreeNode, target int) bool { - vals1 := inorder(root1) - vals2 := inorder(root2) - i, j := 0, len(vals2)-1 - for i < len(vals1) && j >= 0 { - s := vals1[i] + vals2[j] - if s == target { + nums := [2][]int{} + var dfs func(*TreeNode, int) + dfs = func(root *TreeNode, i int) { + if root == nil { + return + } + dfs(root.Left, i) + nums[i] = append(nums[i], root.Val) + dfs(root.Right, i) + } + dfs(root1, 0) + dfs(root2, 1) + i, j := 0, len(nums[1])-1 + for i < len(nums[0]) && j >= 0 { + x := nums[0][i] + nums[1][j] + if x == target { return true } - if s < target { + if x < target { i++ } else { j-- @@ -187,14 +203,53 @@ func twoSumBSTs(root1 *TreeNode, root2 *TreeNode, target int) bool { } return false } +``` -func inorder(root *TreeNode) []int { - if root == nil { - return nil - } - left := inorder(root.Left) - right := inorder(root.Right) - return append(append(left, root.Val), right...) +### **TypeScript** + +```ts +/** + * Definition for a binary tree node. + * class TreeNode { + * val: number + * left: TreeNode | null + * right: TreeNode | null + * constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + * } + */ + +function twoSumBSTs(root1: TreeNode | null, root2: TreeNode | null, target: number): boolean { + const nums: number[][] = Array(2) + .fill(0) + .map(() => []); + const dfs = (root: TreeNode | null, i: number) => { + if (!root) { + return; + } + dfs(root.left, i); + nums[i].push(root.val); + dfs(root.right, i); + }; + dfs(root1, 0); + dfs(root2, 1); + let i = 0; + let j = nums[1].length - 1; + while (i < nums[0].length && j >= 0) { + const x = nums[0][i] + nums[1][j]; + if (x === target) { + return true; + } + if (x < target) { + ++i; + } else { + --j; + } + } + return false; } ``` diff --git a/solution/1200-1299/1214.Two Sum BSTs/Solution.cpp b/solution/1200-1299/1214.Two Sum BSTs/Solution.cpp index 3c6d082c1c93d..dbd7d891a05a3 100644 --- a/solution/1200-1299/1214.Two Sum BSTs/Solution.cpp +++ b/solution/1200-1299/1214.Two Sum BSTs/Solution.cpp @@ -12,27 +12,29 @@ class Solution { public: bool twoSumBSTs(TreeNode* root1, TreeNode* root2, int target) { - vector vals1, vals2; - inorder(root1, vals1); - inorder(root2, vals2); - int i = 0, j = vals2.size() - 1; - while (i < vals1.size() && j >= 0) { - int s = vals1[i] + vals2[j]; - if (s == target) + vector nums[2]; + function dfs = [&](TreeNode* root, int i) { + if (!root) { + return; + } + dfs(root->left, i); + nums[i].push_back(root->val); + dfs(root->right, i); + }; + dfs(root1, 0); + dfs(root2, 1); + int i = 0, j = nums[1].size() - 1; + while (i < nums[0].size() && j >= 0) { + int x = nums[0][i] + nums[1][j]; + if (x == target) { return true; - if (s < target) + } + if (x < target) { ++i; - else + } else { --j; + } } return false; } - - void inorder(TreeNode* root, vector& vals) { - if (root) { - inorder(root->left, vals); - vals.push_back(root->val); - inorder(root->right, vals); - } - } }; \ No newline at end of file diff --git a/solution/1200-1299/1214.Two Sum BSTs/Solution.go b/solution/1200-1299/1214.Two Sum BSTs/Solution.go index 1629589809287..5cb9ca0fb1b7b 100644 --- a/solution/1200-1299/1214.Two Sum BSTs/Solution.go +++ b/solution/1200-1299/1214.Two Sum BSTs/Solution.go @@ -7,28 +7,29 @@ * } */ func twoSumBSTs(root1 *TreeNode, root2 *TreeNode, target int) bool { - vals1 := inorder(root1) - vals2 := inorder(root2) - i, j := 0, len(vals2)-1 - for i < len(vals1) && j >= 0 { - s := vals1[i] + vals2[j] - if s == target { + nums := [2][]int{} + var dfs func(*TreeNode, int) + dfs = func(root *TreeNode, i int) { + if root == nil { + return + } + dfs(root.Left, i) + nums[i] = append(nums[i], root.Val) + dfs(root.Right, i) + } + dfs(root1, 0) + dfs(root2, 1) + i, j := 0, len(nums[1])-1 + for i < len(nums[0]) && j >= 0 { + x := nums[0][i] + nums[1][j] + if x == target { return true } - if s < target { + if x < target { i++ } else { j-- } } return false -} - -func inorder(root *TreeNode) []int { - if root == nil { - return nil - } - left := inorder(root.Left) - right := inorder(root.Right) - return append(append(left, root.Val), right...) } \ No newline at end of file diff --git a/solution/1200-1299/1214.Two Sum BSTs/Solution.java b/solution/1200-1299/1214.Two Sum BSTs/Solution.java index f610e4fc52e94..d1c12b81def2e 100644 --- a/solution/1200-1299/1214.Two Sum BSTs/Solution.java +++ b/solution/1200-1299/1214.Two Sum BSTs/Solution.java @@ -14,18 +14,19 @@ * } */ class Solution { + private List[] nums = new List[2]; + public boolean twoSumBSTs(TreeNode root1, TreeNode root2, int target) { - List vals1 = new ArrayList<>(); - List vals2 = new ArrayList<>(); - inorder(root1, vals1); - inorder(root2, vals2); - int i = 0, j = vals2.size() - 1; - while (i < vals1.size() && j >= 0) { - int s = vals1.get(i) + vals2.get(j); - if (s == target) { + Arrays.setAll(nums, k -> new ArrayList<>()); + dfs(root1, 0); + dfs(root2, 1); + int i = 0, j = nums[1].size() - 1; + while (i < nums[0].size() && j >= 0) { + int x = nums[0].get(i) + nums[1].get(j); + if (x == target) { return true; } - if (s < target) { + if (x < target) { ++i; } else { --j; @@ -34,11 +35,12 @@ public boolean twoSumBSTs(TreeNode root1, TreeNode root2, int target) { return false; } - private void inorder(TreeNode root, List vals) { - if (root != null) { - inorder(root.left, vals); - vals.add(root.val); - inorder(root.right, vals); + private void dfs(TreeNode root, int i) { + if (root == null) { + return; } + dfs(root.left, i); + nums[i].add(root.val); + dfs(root.right, i); } } \ No newline at end of file diff --git a/solution/1200-1299/1214.Two Sum BSTs/Solution.py b/solution/1200-1299/1214.Two Sum BSTs/Solution.py index e68aec7139c6a..4914d78a4ed0a 100644 --- a/solution/1200-1299/1214.Two Sum BSTs/Solution.py +++ b/solution/1200-1299/1214.Two Sum BSTs/Solution.py @@ -5,23 +5,25 @@ # self.left = left # self.right = right class Solution: - def twoSumBSTs(self, root1: TreeNode, root2: TreeNode, target: int) -> bool: - vals1, vals2 = [], [] + def twoSumBSTs( + self, root1: Optional[TreeNode], root2: Optional[TreeNode], target: int + ) -> bool: + def dfs(root: Optional[TreeNode], i: int): + if root is None: + return + dfs(root.left, i) + nums[i].append(root.val) + dfs(root.right, i) - def inorder(root, vals): - if root: - inorder(root.left, vals) - vals.append(root.val) - inorder(root.right, vals) - - inorder(root1, vals1) - inorder(root2, vals2) - - i, j = 0, len(vals2) - 1 - while i < len(vals1) and j >= 0: - if vals1[i] + vals2[j] == target: + nums = [[], []] + dfs(root1, 0) + dfs(root2, 1) + i, j = 0, len(nums[1]) - 1 + while i < len(nums[0]) and ~j: + x = nums[0][i] + nums[1][j] + if x == target: return True - if vals1[i] + vals2[j] < target: + if x < target: i += 1 else: j -= 1 diff --git a/solution/1200-1299/1214.Two Sum BSTs/Solution.ts b/solution/1200-1299/1214.Two Sum BSTs/Solution.ts new file mode 100644 index 0000000000000..d05fa62f95141 --- /dev/null +++ b/solution/1200-1299/1214.Two Sum BSTs/Solution.ts @@ -0,0 +1,43 @@ +/** + * Definition for a binary tree node. + * class TreeNode { + * val: number + * left: TreeNode | null + * right: TreeNode | null + * constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + * } + */ + +function twoSumBSTs(root1: TreeNode | null, root2: TreeNode | null, target: number): boolean { + const nums: number[][] = Array(2) + .fill(0) + .map(() => []); + const dfs = (root: TreeNode | null, i: number) => { + if (!root) { + return; + } + dfs(root.left, i); + nums[i].push(root.val); + dfs(root.right, i); + }; + dfs(root1, 0); + dfs(root2, 1); + let i = 0; + let j = nums[1].length - 1; + while (i < nums[0].length && j >= 0) { + const x = nums[0][i] + nums[1][j]; + if (x === target) { + return true; + } + if (x < target) { + ++i; + } else { + --j; + } + } + return false; +}