diff --git a/basic/sorting/HeapSort/README.md b/basic/sorting/HeapSort/README.md index 62e522c5fa57e..cff9934b0abb2 100644 --- a/basic/sorting/HeapSort/README.md +++ b/basic/sorting/HeapSort/README.md @@ -71,8 +71,6 @@ for (int i = n / 2; i > 0; --i) { -### **Python3** - #### Python3 ```python @@ -112,8 +110,6 @@ for i in range(m): print(' '.join(list(map(str, res)))) ``` -### **Java** - #### Java ```java @@ -169,8 +165,6 @@ public class Main { } ``` -### **Rust** - #### Rust ```rust @@ -236,8 +230,6 @@ fn main() -> io::Result<()> { } ``` -### **Go** - #### Go ```go diff --git "a/lcof/\351\235\242\350\257\225\351\242\23063. \350\202\241\347\245\250\347\232\204\346\234\200\345\244\247\345\210\251\346\266\246/README.md" "b/lcof/\351\235\242\350\257\225\351\242\23063. \350\202\241\347\245\250\347\232\204\346\234\200\345\244\247\345\210\251\346\266\246/README.md" index 6ab24b2393904..a744d37ce56f3 100644 --- "a/lcof/\351\235\242\350\257\225\351\242\23063. \350\202\241\347\245\250\347\232\204\346\234\200\345\244\247\345\210\251\346\266\246/README.md" +++ "b/lcof/\351\235\242\350\257\225\351\242\23063. \350\202\241\347\245\250\347\232\204\346\234\200\345\244\247\345\210\251\346\266\246/README.md" @@ -181,12 +181,12 @@ class Solution { func maxProfit(_ prices: [Int]) -> Int { var mi = Int.max var ans = 0 - + for x in prices { ans = max(ans, x - mi) mi = min(mi, x) } - + return ans } } diff --git "a/lcof/\351\235\242\350\257\225\351\242\23066. \346\236\204\345\273\272\344\271\230\347\247\257\346\225\260\347\273\204/README.md" "b/lcof/\351\235\242\350\257\225\351\242\23066. \346\236\204\345\273\272\344\271\230\347\247\257\346\225\260\347\273\204/README.md" index 3bcd9cd7fef85..5c246de52ddbb 100644 --- "a/lcof/\351\235\242\350\257\225\351\242\23066. \346\236\204\345\273\272\344\271\230\347\247\257\346\225\260\347\273\204/README.md" +++ "b/lcof/\351\235\242\350\257\225\351\242\23066. \346\236\204\345\273\272\344\271\230\347\247\257\346\225\260\347\273\204/README.md" @@ -195,21 +195,21 @@ class Solution { func constructArr(_ a: [Int]) -> [Int] { let n = a.count guard n > 0 else { return [] } - + var ans = [Int](repeating: 1, count: n) - + var left = 1 for i in 0..= 0 || j >= 0 || carry > 0 { let digitA = i >= 0 ? Int(String(aChars[i]))! : 0 let digitB = j >= 0 ? Int(String(bChars[j]))! : 0 - + carry += digitA + digitB result = "\(carry % 2)" + result carry /= 2 - + i -= 1 j -= 1 } - + return result } } diff --git a/solution/0300-0399/0362.Design Hit Counter/README.md b/solution/0300-0399/0362.Design Hit Counter/README.md index 8b7dc45795fa3..83ab02a39a0df 100644 --- a/solution/0300-0399/0362.Design Hit Counter/README.md +++ b/solution/0300-0399/0362.Design Hit Counter/README.md @@ -74,7 +74,11 @@ counter.getHits(301); // 在时刻 301 统计过去 5 分钟内的敲击次数 -### 方法一 +### 方法一:二分查找 + +由于 `timestamp` 是单调递增的,我们可以使用一个数组 `ts` 来存储所有的 `timestamp`,然后在 `getHits` 方法中使用二分查找找到第一个大于等于 `timestamp - 300 + 1` 的位置,然后返回 `ts` 的长度减去这个位置即可。 + +时间复杂度方面,`hit` 方法的时间复杂度为 $O(1)$,`getHits` 方法的时间复杂度为 $O(\log n)$。其中 $n$ 为 `ts` 的长度。 @@ -82,25 +86,15 @@ counter.getHits(301); // 在时刻 301 统计过去 5 分钟内的敲击次数 ```python class HitCounter: + def __init__(self): - """ - Initialize your data structure here. - """ - self.counter = Counter() + self.ts = [] def hit(self, timestamp: int) -> None: - """ - Record a hit. - @param timestamp - The current timestamp (in seconds granularity). - """ - self.counter[timestamp] += 1 + self.ts.append(timestamp) def getHits(self, timestamp: int) -> int: - """ - Return the number of hits in the past 5 minutes. - @param timestamp - The current timestamp (in seconds granularity). - """ - return sum([v for t, v in self.counter.items() if t + 300 > timestamp]) + return len(self.ts) - bisect_left(self.ts, timestamp - 300 + 1) # Your HitCounter object will be instantiated and called as such: @@ -113,34 +107,31 @@ class HitCounter: ```java class HitCounter { + private List ts = new ArrayList<>(); - private Map counter; - - /** Initialize your data structure here. */ public HitCounter() { - counter = new HashMap<>(); } - /** - Record a hit. - @param timestamp - The current timestamp (in seconds granularity). - */ public void hit(int timestamp) { - counter.put(timestamp, counter.getOrDefault(timestamp, 0) + 1); + ts.add(timestamp); } - /** - Return the number of hits in the past 5 minutes. - @param timestamp - The current timestamp (in seconds granularity). - */ public int getHits(int timestamp) { - int hits = 0; - for (Map.Entry entry : counter.entrySet()) { - if (entry.getKey() + 300 > timestamp) { - hits += entry.getValue(); + int l = search(timestamp - 300 + 1); + return ts.size() - l; + } + + private int search(int x) { + int l = 0, r = ts.size(); + while (l < r) { + int mid = (l + r) >> 1; + if (ts.get(mid) >= x) { + r = mid; + } else { + l = mid + 1; } } - return hits; + return l; } } @@ -152,39 +143,142 @@ class HitCounter { */ ``` +#### C++ + +```cpp +class HitCounter { +public: + HitCounter() { + + } + + void hit(int timestamp) { + ts.push_back(timestamp); + } + + int getHits(int timestamp) { + return ts.end() - lower_bound(ts.begin(), ts.end(), timestamp - 300 + 1); + } + +private: + vector ts; +}; + +/** + * Your HitCounter object will be instantiated and called as such: + * HitCounter* obj = new HitCounter(); + * obj->hit(timestamp); + * int param_2 = obj->getHits(timestamp); + */ +``` + +#### Go + +```go +type HitCounter struct { + ts []int +} + +func Constructor() HitCounter { + return HitCounter{} +} + +func (this *HitCounter) Hit(timestamp int) { + this.ts = append(this.ts, timestamp) +} + +func (this *HitCounter) GetHits(timestamp int) int { + return len(this.ts) - sort.SearchInts(this.ts, timestamp-300+1) +} + +/** + * Your HitCounter object will be instantiated and called as such: + * obj := Constructor(); + * obj.Hit(timestamp); + * param_2 := obj.GetHits(timestamp); + */ +``` + +#### TypeScript + +```ts +class HitCounter { + private ts: number[] = []; + + constructor() {} + + hit(timestamp: number): void { + this.ts.push(timestamp); + } + + getHits(timestamp: number): number { + const search = (x: number) => { + let [l, r] = [0, this.ts.length]; + while (l < r) { + const mid = (l + r) >> 1; + if (this.ts[mid] >= x) { + r = mid; + } else { + l = mid + 1; + } + } + return l; + }; + return this.ts.length - search(timestamp - 300 + 1); + } +} + +/** + * Your HitCounter object will be instantiated and called as such: + * var obj = new HitCounter() + * obj.hit(timestamp) + * var param_2 = obj.getHits(timestamp) + */ +``` + #### Rust ```rust -use std::{ collections::BinaryHeap, cmp::Reverse }; - struct HitCounter { - /// A min heap - pq: BinaryHeap>, + ts: Vec, } +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ impl HitCounter { fn new() -> Self { - Self { - pq: BinaryHeap::new(), - } + HitCounter { ts: Vec::new() } } fn hit(&mut self, timestamp: i32) { - self.pq.push(Reverse(timestamp)); + self.ts.push(timestamp); } - fn get_hits(&mut self, timestamp: i32) -> i32 { - while let Some(Reverse(min_elem)) = self.pq.peek() { - if *min_elem <= timestamp - 300 { - self.pq.pop(); + fn get_hits(&self, timestamp: i32) -> i32 { + let l = self.search(timestamp - 300 + 1); + (self.ts.len() - l) as i32 + } + + fn search(&self, x: i32) -> usize { + let (mut l, mut r) = (0, self.ts.len()); + while l < r { + let mid = (l + r) / 2; + if self.ts[mid] >= x { + r = mid; } else { - break; + l = mid + 1; } } - - self.pq.len() as i32 + l } -} +}/** + * Your HitCounter object will be instantiated and called as such: + * let obj = HitCounter::new(); + * obj.hit(timestamp); + * let ret_2: i32 = obj.get_hits(timestamp); + */ ``` diff --git a/solution/0300-0399/0362.Design Hit Counter/README_EN.md b/solution/0300-0399/0362.Design Hit Counter/README_EN.md index 4d2ea674fb8c7..987e051c7c581 100644 --- a/solution/0300-0399/0362.Design Hit Counter/README_EN.md +++ b/solution/0300-0399/0362.Design Hit Counter/README_EN.md @@ -71,7 +71,11 @@ hitCounter.getHits(301); // get hits at timestamp 301, return 3. -### Solution 1 +### Solution 1: Binary Search + +Since `timestamp` is monotonically increasing, we can use an array `ts` to store all `timestamp`s. Then in the `getHits` method, we use binary search to find the first position that is greater than or equal to `timestamp - 300 + 1`, and then return the length of `ts` minus this position. + +In terms of time complexity, the time complexity of the `hit` method is $O(1)$, and the time complexity of the `getHits` method is $O(\log n)$. Where $n$ is the length of `ts`. @@ -79,25 +83,15 @@ hitCounter.getHits(301); // get hits at timestamp 301, return 3. ```python class HitCounter: + def __init__(self): - """ - Initialize your data structure here. - """ - self.counter = Counter() + self.ts = [] def hit(self, timestamp: int) -> None: - """ - Record a hit. - @param timestamp - The current timestamp (in seconds granularity). - """ - self.counter[timestamp] += 1 + self.ts.append(timestamp) def getHits(self, timestamp: int) -> int: - """ - Return the number of hits in the past 5 minutes. - @param timestamp - The current timestamp (in seconds granularity). - """ - return sum([v for t, v in self.counter.items() if t + 300 > timestamp]) + return len(self.ts) - bisect_left(self.ts, timestamp - 300 + 1) # Your HitCounter object will be instantiated and called as such: @@ -110,34 +104,31 @@ class HitCounter: ```java class HitCounter { + private List ts = new ArrayList<>(); - private Map counter; - - /** Initialize your data structure here. */ public HitCounter() { - counter = new HashMap<>(); } - /** - Record a hit. - @param timestamp - The current timestamp (in seconds granularity). - */ public void hit(int timestamp) { - counter.put(timestamp, counter.getOrDefault(timestamp, 0) + 1); + ts.add(timestamp); } - /** - Return the number of hits in the past 5 minutes. - @param timestamp - The current timestamp (in seconds granularity). - */ public int getHits(int timestamp) { - int hits = 0; - for (Map.Entry entry : counter.entrySet()) { - if (entry.getKey() + 300 > timestamp) { - hits += entry.getValue(); + int l = search(timestamp - 300 + 1); + return ts.size() - l; + } + + private int search(int x) { + int l = 0, r = ts.size(); + while (l < r) { + int mid = (l + r) >> 1; + if (ts.get(mid) >= x) { + r = mid; + } else { + l = mid + 1; } } - return hits; + return l; } } @@ -149,39 +140,142 @@ class HitCounter { */ ``` +#### C++ + +```cpp +class HitCounter { +public: + HitCounter() { + + } + + void hit(int timestamp) { + ts.push_back(timestamp); + } + + int getHits(int timestamp) { + return ts.end() - lower_bound(ts.begin(), ts.end(), timestamp - 300 + 1); + } + +private: + vector ts; +}; + +/** + * Your HitCounter object will be instantiated and called as such: + * HitCounter* obj = new HitCounter(); + * obj->hit(timestamp); + * int param_2 = obj->getHits(timestamp); + */ +``` + +#### Go + +```go +type HitCounter struct { + ts []int +} + +func Constructor() HitCounter { + return HitCounter{} +} + +func (this *HitCounter) Hit(timestamp int) { + this.ts = append(this.ts, timestamp) +} + +func (this *HitCounter) GetHits(timestamp int) int { + return len(this.ts) - sort.SearchInts(this.ts, timestamp-300+1) +} + +/** + * Your HitCounter object will be instantiated and called as such: + * obj := Constructor(); + * obj.Hit(timestamp); + * param_2 := obj.GetHits(timestamp); + */ +``` + +#### TypeScript + +```ts +class HitCounter { + private ts: number[] = []; + + constructor() {} + + hit(timestamp: number): void { + this.ts.push(timestamp); + } + + getHits(timestamp: number): number { + const search = (x: number) => { + let [l, r] = [0, this.ts.length]; + while (l < r) { + const mid = (l + r) >> 1; + if (this.ts[mid] >= x) { + r = mid; + } else { + l = mid + 1; + } + } + return l; + }; + return this.ts.length - search(timestamp - 300 + 1); + } +} + +/** + * Your HitCounter object will be instantiated and called as such: + * var obj = new HitCounter() + * obj.hit(timestamp) + * var param_2 = obj.getHits(timestamp) + */ +``` + #### Rust ```rust -use std::{ collections::BinaryHeap, cmp::Reverse }; - struct HitCounter { - /// A min heap - pq: BinaryHeap>, + ts: Vec, } +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ impl HitCounter { fn new() -> Self { - Self { - pq: BinaryHeap::new(), - } + HitCounter { ts: Vec::new() } } fn hit(&mut self, timestamp: i32) { - self.pq.push(Reverse(timestamp)); + self.ts.push(timestamp); } - fn get_hits(&mut self, timestamp: i32) -> i32 { - while let Some(Reverse(min_elem)) = self.pq.peek() { - if *min_elem <= timestamp - 300 { - self.pq.pop(); + fn get_hits(&self, timestamp: i32) -> i32 { + let l = self.search(timestamp - 300 + 1); + (self.ts.len() - l) as i32 + } + + fn search(&self, x: i32) -> usize { + let (mut l, mut r) = (0, self.ts.len()); + while l < r { + let mid = (l + r) / 2; + if self.ts[mid] >= x { + r = mid; } else { - break; + l = mid + 1; } } - - self.pq.len() as i32 + l } -} +}/** + * Your HitCounter object will be instantiated and called as such: + * let obj = HitCounter::new(); + * obj.hit(timestamp); + * let ret_2: i32 = obj.get_hits(timestamp); + */ ``` diff --git a/solution/0300-0399/0362.Design Hit Counter/Solution.cpp b/solution/0300-0399/0362.Design Hit Counter/Solution.cpp new file mode 100644 index 0000000000000..81e189454dca2 --- /dev/null +++ b/solution/0300-0399/0362.Design Hit Counter/Solution.cpp @@ -0,0 +1,23 @@ +class HitCounter { +public: + HitCounter() { + } + + void hit(int timestamp) { + ts.push_back(timestamp); + } + + int getHits(int timestamp) { + return ts.end() - lower_bound(ts.begin(), ts.end(), timestamp - 300 + 1); + } + +private: + vector ts; +}; + +/** + * Your HitCounter object will be instantiated and called as such: + * HitCounter* obj = new HitCounter(); + * obj->hit(timestamp); + * int param_2 = obj->getHits(timestamp); + */ \ No newline at end of file diff --git a/solution/0300-0399/0362.Design Hit Counter/Solution.go b/solution/0300-0399/0362.Design Hit Counter/Solution.go new file mode 100644 index 0000000000000..523bd51d5b02e --- /dev/null +++ b/solution/0300-0399/0362.Design Hit Counter/Solution.go @@ -0,0 +1,22 @@ +type HitCounter struct { + ts []int +} + +func Constructor() HitCounter { + return HitCounter{} +} + +func (this *HitCounter) Hit(timestamp int) { + this.ts = append(this.ts, timestamp) +} + +func (this *HitCounter) GetHits(timestamp int) int { + return len(this.ts) - sort.SearchInts(this.ts, timestamp-300+1) +} + +/** + * Your HitCounter object will be instantiated and called as such: + * obj := Constructor(); + * obj.Hit(timestamp); + * param_2 := obj.GetHits(timestamp); + */ \ No newline at end of file diff --git a/solution/0300-0399/0362.Design Hit Counter/Solution.java b/solution/0300-0399/0362.Design Hit Counter/Solution.java index fba5ebcc9832e..9f8d781d6127e 100644 --- a/solution/0300-0399/0362.Design Hit Counter/Solution.java +++ b/solution/0300-0399/0362.Design Hit Counter/Solution.java @@ -1,32 +1,29 @@ class HitCounter { + private List ts = new ArrayList<>(); - private Map counter; - - /** Initialize your data structure here. */ public HitCounter() { - counter = new HashMap<>(); } - /** - Record a hit. - @param timestamp - The current timestamp (in seconds granularity). - */ public void hit(int timestamp) { - counter.put(timestamp, counter.getOrDefault(timestamp, 0) + 1); + ts.add(timestamp); } - /** - Return the number of hits in the past 5 minutes. - @param timestamp - The current timestamp (in seconds granularity). - */ public int getHits(int timestamp) { - int hits = 0; - for (Map.Entry entry : counter.entrySet()) { - if (entry.getKey() + 300 > timestamp) { - hits += entry.getValue(); + int l = search(timestamp - 300 + 1); + return ts.size() - l; + } + + private int search(int x) { + int l = 0, r = ts.size(); + while (l < r) { + int mid = (l + r) >> 1; + if (ts.get(mid) >= x) { + r = mid; + } else { + l = mid + 1; } } - return hits; + return l; } } diff --git a/solution/0300-0399/0362.Design Hit Counter/Solution.py b/solution/0300-0399/0362.Design Hit Counter/Solution.py index 8a66c8382a1a1..4a4e5a22d0247 100644 --- a/solution/0300-0399/0362.Design Hit Counter/Solution.py +++ b/solution/0300-0399/0362.Design Hit Counter/Solution.py @@ -1,23 +1,13 @@ class HitCounter: + def __init__(self): - """ - Initialize your data structure here. - """ - self.counter = Counter() + self.ts = [] def hit(self, timestamp: int) -> None: - """ - Record a hit. - @param timestamp - The current timestamp (in seconds granularity). - """ - self.counter[timestamp] += 1 + self.ts.append(timestamp) def getHits(self, timestamp: int) -> int: - """ - Return the number of hits in the past 5 minutes. - @param timestamp - The current timestamp (in seconds granularity). - """ - return sum([v for t, v in self.counter.items() if t + 300 > timestamp]) + return len(self.ts) - bisect_left(self.ts, timestamp - 300 + 1) # Your HitCounter object will be instantiated and called as such: diff --git a/solution/0300-0399/0362.Design Hit Counter/Solution.rs b/solution/0300-0399/0362.Design Hit Counter/Solution.rs index 42fbbc6c55735..025244f80ab6a 100644 --- a/solution/0300-0399/0362.Design Hit Counter/Solution.rs +++ b/solution/0300-0399/0362.Design Hit Counter/Solution.rs @@ -1,30 +1,40 @@ -use std::{ collections::BinaryHeap, cmp::Reverse }; - struct HitCounter { - /// A min heap - pq: BinaryHeap>, + ts: Vec, } +/** + * `&self` means the method takes an immutable reference. + * If you need a mutable reference, change it to `&mut self` instead. + */ impl HitCounter { fn new() -> Self { - Self { - pq: BinaryHeap::new(), - } + HitCounter { ts: Vec::new() } } fn hit(&mut self, timestamp: i32) { - self.pq.push(Reverse(timestamp)); + self.ts.push(timestamp); + } + + fn get_hits(&self, timestamp: i32) -> i32 { + let l = self.search(timestamp - 300 + 1); + (self.ts.len() - l) as i32 } - fn get_hits(&mut self, timestamp: i32) -> i32 { - while let Some(Reverse(min_elem)) = self.pq.peek() { - if *min_elem <= timestamp - 300 { - self.pq.pop(); + fn search(&self, x: i32) -> usize { + let (mut l, mut r) = (0, self.ts.len()); + while l < r { + let mid = (l + r) / 2; + if self.ts[mid] >= x { + r = mid; } else { - break; + l = mid + 1; } } - - self.pq.len() as i32 + l } -} +}/** + * Your HitCounter object will be instantiated and called as such: + * let obj = HitCounter::new(); + * obj.hit(timestamp); + * let ret_2: i32 = obj.get_hits(timestamp); + */ diff --git a/solution/0300-0399/0362.Design Hit Counter/Solution.ts b/solution/0300-0399/0362.Design Hit Counter/Solution.ts new file mode 100644 index 0000000000000..b75d7cacc9a1e --- /dev/null +++ b/solution/0300-0399/0362.Design Hit Counter/Solution.ts @@ -0,0 +1,32 @@ +class HitCounter { + private ts: number[] = []; + + constructor() {} + + hit(timestamp: number): void { + this.ts.push(timestamp); + } + + getHits(timestamp: number): number { + const search = (x: number) => { + let [l, r] = [0, this.ts.length]; + while (l < r) { + const mid = (l + r) >> 1; + if (this.ts[mid] >= x) { + r = mid; + } else { + l = mid + 1; + } + } + return l; + }; + return this.ts.length - search(timestamp - 300 + 1); + } +} + +/** + * Your HitCounter object will be instantiated and called as such: + * var obj = new HitCounter() + * obj.hit(timestamp) + * var param_2 = obj.getHits(timestamp) + */ diff --git a/solution/0300-0399/0363.Max Sum of Rectangle No Larger Than K/README_EN.md b/solution/0300-0399/0363.Max Sum of Rectangle No Larger Than K/README_EN.md index 88c8e562b3209..42c55f6852f72 100644 --- a/solution/0300-0399/0363.Max Sum of Rectangle No Larger Than K/README_EN.md +++ b/solution/0300-0399/0363.Max Sum of Rectangle No Larger Than K/README_EN.md @@ -60,7 +60,13 @@ tags: -### Solution 1 +### Solution 1: Enumerate Boundaries + Ordered Set + +We can enumerate the upper and lower boundaries $i$ and $j$ of the rectangle, then calculate the sum of the elements in each column within this boundary, and record it in the array $nums$. The problem is transformed into how to find the maximum subarray sum not exceeding $k$ in the array $nums$. + +We can use an ordered set to quickly find the maximum value less than or equal to $x$, thereby obtaining a subarray with the maximum subarray sum not exceeding $k$. + +The time complexity is $O(m^2 \times n \times \log n)$, and the space complexity is $O(n)$. diff --git a/solution/0300-0399/0364.Nested List Weight Sum II/README.md b/solution/0300-0399/0364.Nested List Weight Sum II/README.md index 97722ef3318f0..863445b2ff5ee 100644 --- a/solution/0300-0399/0364.Nested List Weight Sum II/README.md +++ b/solution/0300-0399/0364.Nested List Weight Sum II/README.md @@ -62,7 +62,35 @@ tags: -### 方法一 +### 方法一:DFS + +我们不妨假设整数分别为 $a_1, a_2, \cdots, a_n$,它们的深度分别为 $d_1, d_2, \cdots, d_n$,最大深度为 $\text{maxDepth}$,那么答案就是: + +$$ +a_1 \times \text{maxDepth} - a_1 \times d_1 + a_1 + a_2 \times \text{maxDepth} - a_2 \times d_2 + a_2 + \cdots + a_n \times \text{maxDepth} - a_n \times d_n + a_n +$$ + +即: + +$$ +(\text{maxDepth} + 1) \times (a_1 + a_2 + \cdots + a_n) - (a_1 \times d_1 + a_2 \times d_2 + \cdots + a_n \times d_n) +$$ + +如果我们记所有整数的和为 $s$,所有整数乘以深度的和为 $ws$,那么答案就是: + +$$ +(\text{maxDepth} + 1) \times s - ws +$$ + +因此,我们设计一个函数 $dfs(x, d)$,表示从 $x$ 开始,深度为 $d$ 开始搜索,函数 $dfs(x, d)$ 的执行过程如下: + +- 我们先更新 $\text{maxDepth} = \max(\text{maxDepth}, d)$; +- 如果 $x$ 是一个整数,那么我们更新 $s = s + x$, $ws = ws + x \times d$; +- 否则,我们递归地遍历 $x$ 的每一个元素 $y$,调用 $dfs(y, d + 1)$。 + +我们遍历整个列表,对于每一个元素 $x$,我们调用 $dfs(x, 1)$,最终返回 $(\text{maxDepth} + 1) \times s - ws$ 即可。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为整数的个数。 @@ -113,25 +141,20 @@ tags: # """ class Solution: def depthSumInverse(self, nestedList: List[NestedInteger]) -> int: - def max_depth(nestedList): - depth = 1 - for item in nestedList: - if item.isInteger(): - continue - depth = max(depth, max_depth(item.getList()) + 1) - return depth - - def dfs(nestedList, max_depth): - depth_sum = 0 - for item in nestedList: - if item.isInteger(): - depth_sum += item.getInteger() * max_depth - else: - depth_sum += dfs(item.getList(), max_depth - 1) - return depth_sum - - depth = max_depth(nestedList) - return dfs(nestedList, depth) + def dfs(x, d): + nonlocal maxDepth, s, ws + maxDepth = max(maxDepth, d) + if x.isInteger(): + s += x.getInteger() + ws += x.getInteger() * d + else: + for y in x.getList(): + dfs(y, d + 1) + + maxDepth = s = ws = 0 + for x in nestedList: + dfs(x, 1) + return (maxDepth + 1) * s - ws ``` #### Java @@ -166,33 +189,194 @@ class Solution: * } */ class Solution { + private int maxDepth; + private int ws; + private int s; + public int depthSumInverse(List nestedList) { - int depth = maxDepth(nestedList); - return dfs(nestedList, depth); + for (NestedInteger x : nestedList) { + dfs(x, 1); + } + return (maxDepth + 1) * s - ws; } - private int maxDepth(List nestedList) { - int depth = 1; - for (NestedInteger item : nestedList) { - if (item.isInteger()) { - continue; + private void dfs(NestedInteger x, int d) { + maxDepth = Math.max(maxDepth, d); + if (x.isInteger()) { + ws += x.getInteger() * d; + s += x.getInteger(); + } else { + for (NestedInteger y : x.getList()) { + dfs(y, d + 1); } - depth = Math.max(depth, 1 + maxDepth(item.getList())); } - return depth; } +} +``` - private int dfs(List nestedList, int depth) { - int depthSum = 0; - for (NestedInteger item : nestedList) { - if (item.isInteger()) { - depthSum += item.getInteger() * depth; +#### C++ + +```cpp +/** + * // This is the interface that allows for creating nested lists. + * // You should not implement it, or speculate about its implementation + * class NestedInteger { + * public: + * // Constructor initializes an empty nested list. + * NestedInteger(); + * + * // Constructor initializes a single integer. + * NestedInteger(int value); + * + * // Return true if this NestedInteger holds a single integer, rather than a nested list. + * bool isInteger() const; + * + * // Return the single integer that this NestedInteger holds, if it holds a single integer + * // The result is undefined if this NestedInteger holds a nested list + * int getInteger() const; + * + * // Set this NestedInteger to hold a single integer. + * void setInteger(int value); + * + * // Set this NestedInteger to hold a nested list and adds a nested integer to it. + * void add(const NestedInteger &ni); + * + * // Return the nested list that this NestedInteger holds, if it holds a nested list + * // The result is undefined if this NestedInteger holds a single integer + * const vector &getList() const; + * }; + */ +class Solution { +public: + int depthSumInverse(vector& nestedList) { + int maxDepth = 0, ws = 0, s = 0; + function dfs = [&](NestedInteger& x, int d) { + maxDepth = max(maxDepth, d); + if (x.isInteger()) { + ws += x.getInteger() * d; + s += x.getInteger(); } else { - depthSum += dfs(item.getList(), depth - 1); + for (auto& y : x.getList()) { + dfs(y, d + 1); + } + } + }; + for (auto& x : nestedList) { + dfs(x, 1); + } + return (maxDepth + 1) * s - ws; + } +}; +``` + +#### Go + +```go +/** + * // This is the interface that allows for creating nested lists. + * // You should not implement it, or speculate about its implementation + * type NestedInteger struct { + * } + * + * // Return true if this NestedInteger holds a single integer, rather than a nested list. + * func (n NestedInteger) IsInteger() bool {} + * + * // Return the single integer that this NestedInteger holds, if it holds a single integer + * // The result is undefined if this NestedInteger holds a nested list + * // So before calling this method, you should have a check + * func (n NestedInteger) GetInteger() int {} + * + * // Set this NestedInteger to hold a single integer. + * func (n *NestedInteger) SetInteger(value int) {} + * + * // Set this NestedInteger to hold a nested list and adds a nested integer to it. + * func (n *NestedInteger) Add(elem NestedInteger) {} + * + * // Return the nested list that this NestedInteger holds, if it holds a nested list + * // The list length is zero if this NestedInteger holds a single integer + * // You can access NestedInteger's List element directly if you want to modify it + * func (n NestedInteger) GetList() []*NestedInteger {} + */ +func depthSumInverse(nestedList []*NestedInteger) int { + var maxDepth, ws, s int + var dfs func(*NestedInteger, int) + dfs = func(x *NestedInteger, d int) { + maxDepth = max(maxDepth, d) + if x.IsInteger() { + ws += x.GetInteger() * d + s += x.GetInteger() + } else { + for _, y := range x.GetList() { + dfs(y, d+1) + } + } + } + for _, x := range nestedList { + dfs(x, 1) + } + return (maxDepth+1)*s - ws +} +``` + +#### TypeScript + +```ts +/** + * // This is the interface that allows for creating nested lists. + * // You should not implement it, or speculate about its implementation + * class NestedInteger { + * If value is provided, then it holds a single integer + * Otherwise it holds an empty nested list + * constructor(value?: number) { + * ... + * }; + * + * Return true if this NestedInteger holds a single integer, rather than a nested list. + * isInteger(): boolean { + * ... + * }; + * + * Return the single integer that this NestedInteger holds, if it holds a single integer + * Return null if this NestedInteger holds a nested list + * getInteger(): number | null { + * ... + * }; + * + * Set this NestedInteger to hold a single integer equal to value. + * setInteger(value: number) { + * ... + * }; + * + * Set this NestedInteger to hold a nested list and adds a nested integer elem to it. + * add(elem: NestedInteger) { + * ... + * }; + * + * Return the nested list that this NestedInteger holds, + * or an empty list if this NestedInteger holds a single integer + * getList(): NestedInteger[] { + * ... + * }; + * }; + */ + +function depthSumInverse(nestedList: NestedInteger[]): number { + let [maxDepth, ws, s] = [0, 0, 0]; + const dfs = (x: NestedInteger, d: number) => { + maxDepth = Math.max(maxDepth, d); + if (x.isInteger()) { + ws += x.getInteger() * d; + s += x.getInteger(); + } else { + for (const y of x.getList()) { + dfs(y, d + 1); } } - return depthSum; + }; + for (const x of nestedList) { + dfs(x, 1); } + return (maxDepth + 1) * s - ws; } ``` @@ -242,29 +426,22 @@ class Solution { * @return {number} */ var depthSumInverse = function (nestedList) { - const maxDepth = nestedList => { - let depth = 1; - for (const item of nestedList) { - if (item.isInteger()) { - continue; + let [maxDepth, ws, s] = [0, 0, 0]; + const dfs = (x, d) => { + maxDepth = Math.max(maxDepth, d); + if (x.isInteger()) { + ws += x.getInteger() * d; + s += x.getInteger(); + } else { + for (const y of x.getList()) { + dfs(y, d + 1); } - depth = Math.max(depth, 1 + maxDepth(item.getList())); } - return depth; }; - const dfs = (nestedList, depth) => { - let depthSum = 0; - for (const item of nestedList) { - if (item.isInteger()) { - depthSum += item.getInteger() * depth; - } else { - depthSum += dfs(item.getList(), depth - 1); - } - } - return depthSum; - }; - const depth = maxDepth(nestedList); - return dfs(nestedList, depth); + for (const x of nestedList) { + dfs(x, 1); + } + return (maxDepth + 1) * s - ws; }; ``` diff --git a/solution/0300-0399/0364.Nested List Weight Sum II/README_EN.md b/solution/0300-0399/0364.Nested List Weight Sum II/README_EN.md index affa7b248b19c..cb1f774da5472 100644 --- a/solution/0300-0399/0364.Nested List Weight Sum II/README_EN.md +++ b/solution/0300-0399/0364.Nested List Weight Sum II/README_EN.md @@ -60,7 +60,35 @@ tags: -### Solution 1 +### Solution 1: DFS + +Let's assume the integers are $a_1, a_2, \cdots, a_n$, their depths are $d_1, d_2, \cdots, d_n$, the maximum depth is $\text{maxDepth}$, then the answer is: + +$$ +a_1 \times \text{maxDepth} - a_1 \times d_1 + a_1 + a_2 \times \text{maxDepth} - a_2 \times d_2 + a_2 + \cdots + a_n \times \text{maxDepth} - a_n \times d_n + a_n +$$ + +which is: + +$$ +(\text{maxDepth} + 1) \times (a_1 + a_2 + \cdots + a_n) - (a_1 \times d_1 + a_2 \times d_2 + \cdots + a_n \times d_n) +$$ + +If we denote the sum of all integers as $s$, and the sum of each integer multiplied by its depth as $ws$, then the answer is: + +$$ +(\text{maxDepth} + 1) \times s - ws +$$ + +Therefore, we design a function $dfs(x, d)$, which starts searching from $x$ with depth $d$. The execution process of $dfs(x, d)$ is as follows: + +- We first update $\text{maxDepth} = \max(\text{maxDepth}, d)$; +- If $x$ is an integer, then we update $s = s + x$, $ws = ws + x \times d$; +- Otherwise, we recursively traverse each element $y$ of $x$, and call $dfs(y, d + 1)$. + +We traverse the entire list, for each element $x$, we call $dfs(x, 1)$, and finally return $(\text{maxDepth} + 1) \times s - ws$. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Where $n$ is the number of integers. @@ -111,25 +139,20 @@ tags: # """ class Solution: def depthSumInverse(self, nestedList: List[NestedInteger]) -> int: - def max_depth(nestedList): - depth = 1 - for item in nestedList: - if item.isInteger(): - continue - depth = max(depth, max_depth(item.getList()) + 1) - return depth - - def dfs(nestedList, max_depth): - depth_sum = 0 - for item in nestedList: - if item.isInteger(): - depth_sum += item.getInteger() * max_depth - else: - depth_sum += dfs(item.getList(), max_depth - 1) - return depth_sum - - depth = max_depth(nestedList) - return dfs(nestedList, depth) + def dfs(x, d): + nonlocal maxDepth, s, ws + maxDepth = max(maxDepth, d) + if x.isInteger(): + s += x.getInteger() + ws += x.getInteger() * d + else: + for y in x.getList(): + dfs(y, d + 1) + + maxDepth = s = ws = 0 + for x in nestedList: + dfs(x, 1) + return (maxDepth + 1) * s - ws ``` #### Java @@ -164,33 +187,194 @@ class Solution: * } */ class Solution { + private int maxDepth; + private int ws; + private int s; + public int depthSumInverse(List nestedList) { - int depth = maxDepth(nestedList); - return dfs(nestedList, depth); + for (NestedInteger x : nestedList) { + dfs(x, 1); + } + return (maxDepth + 1) * s - ws; } - private int maxDepth(List nestedList) { - int depth = 1; - for (NestedInteger item : nestedList) { - if (item.isInteger()) { - continue; + private void dfs(NestedInteger x, int d) { + maxDepth = Math.max(maxDepth, d); + if (x.isInteger()) { + ws += x.getInteger() * d; + s += x.getInteger(); + } else { + for (NestedInteger y : x.getList()) { + dfs(y, d + 1); } - depth = Math.max(depth, 1 + maxDepth(item.getList())); } - return depth; } +} +``` + +#### C++ - private int dfs(List nestedList, int depth) { - int depthSum = 0; - for (NestedInteger item : nestedList) { - if (item.isInteger()) { - depthSum += item.getInteger() * depth; +```cpp +/** + * // This is the interface that allows for creating nested lists. + * // You should not implement it, or speculate about its implementation + * class NestedInteger { + * public: + * // Constructor initializes an empty nested list. + * NestedInteger(); + * + * // Constructor initializes a single integer. + * NestedInteger(int value); + * + * // Return true if this NestedInteger holds a single integer, rather than a nested list. + * bool isInteger() const; + * + * // Return the single integer that this NestedInteger holds, if it holds a single integer + * // The result is undefined if this NestedInteger holds a nested list + * int getInteger() const; + * + * // Set this NestedInteger to hold a single integer. + * void setInteger(int value); + * + * // Set this NestedInteger to hold a nested list and adds a nested integer to it. + * void add(const NestedInteger &ni); + * + * // Return the nested list that this NestedInteger holds, if it holds a nested list + * // The result is undefined if this NestedInteger holds a single integer + * const vector &getList() const; + * }; + */ +class Solution { +public: + int depthSumInverse(vector& nestedList) { + int maxDepth = 0, ws = 0, s = 0; + function dfs = [&](NestedInteger& x, int d) { + maxDepth = max(maxDepth, d); + if (x.isInteger()) { + ws += x.getInteger() * d; + s += x.getInteger(); } else { - depthSum += dfs(item.getList(), depth - 1); + for (auto& y : x.getList()) { + dfs(y, d + 1); + } } + }; + for (auto& x : nestedList) { + dfs(x, 1); } - return depthSum; + return (maxDepth + 1) * s - ws; } +}; +``` + +#### Go + +```go +/** + * // This is the interface that allows for creating nested lists. + * // You should not implement it, or speculate about its implementation + * type NestedInteger struct { + * } + * + * // Return true if this NestedInteger holds a single integer, rather than a nested list. + * func (n NestedInteger) IsInteger() bool {} + * + * // Return the single integer that this NestedInteger holds, if it holds a single integer + * // The result is undefined if this NestedInteger holds a nested list + * // So before calling this method, you should have a check + * func (n NestedInteger) GetInteger() int {} + * + * // Set this NestedInteger to hold a single integer. + * func (n *NestedInteger) SetInteger(value int) {} + * + * // Set this NestedInteger to hold a nested list and adds a nested integer to it. + * func (n *NestedInteger) Add(elem NestedInteger) {} + * + * // Return the nested list that this NestedInteger holds, if it holds a nested list + * // The list length is zero if this NestedInteger holds a single integer + * // You can access NestedInteger's List element directly if you want to modify it + * func (n NestedInteger) GetList() []*NestedInteger {} + */ +func depthSumInverse(nestedList []*NestedInteger) int { + var maxDepth, ws, s int + var dfs func(*NestedInteger, int) + dfs = func(x *NestedInteger, d int) { + maxDepth = max(maxDepth, d) + if x.IsInteger() { + ws += x.GetInteger() * d + s += x.GetInteger() + } else { + for _, y := range x.GetList() { + dfs(y, d+1) + } + } + } + for _, x := range nestedList { + dfs(x, 1) + } + return (maxDepth+1)*s - ws +} +``` + +#### TypeScript + +```ts +/** + * // This is the interface that allows for creating nested lists. + * // You should not implement it, or speculate about its implementation + * class NestedInteger { + * If value is provided, then it holds a single integer + * Otherwise it holds an empty nested list + * constructor(value?: number) { + * ... + * }; + * + * Return true if this NestedInteger holds a single integer, rather than a nested list. + * isInteger(): boolean { + * ... + * }; + * + * Return the single integer that this NestedInteger holds, if it holds a single integer + * Return null if this NestedInteger holds a nested list + * getInteger(): number | null { + * ... + * }; + * + * Set this NestedInteger to hold a single integer equal to value. + * setInteger(value: number) { + * ... + * }; + * + * Set this NestedInteger to hold a nested list and adds a nested integer elem to it. + * add(elem: NestedInteger) { + * ... + * }; + * + * Return the nested list that this NestedInteger holds, + * or an empty list if this NestedInteger holds a single integer + * getList(): NestedInteger[] { + * ... + * }; + * }; + */ + +function depthSumInverse(nestedList: NestedInteger[]): number { + let [maxDepth, ws, s] = [0, 0, 0]; + const dfs = (x: NestedInteger, d: number) => { + maxDepth = Math.max(maxDepth, d); + if (x.isInteger()) { + ws += x.getInteger() * d; + s += x.getInteger(); + } else { + for (const y of x.getList()) { + dfs(y, d + 1); + } + } + }; + for (const x of nestedList) { + dfs(x, 1); + } + return (maxDepth + 1) * s - ws; } ``` @@ -240,29 +424,22 @@ class Solution { * @return {number} */ var depthSumInverse = function (nestedList) { - const maxDepth = nestedList => { - let depth = 1; - for (const item of nestedList) { - if (item.isInteger()) { - continue; + let [maxDepth, ws, s] = [0, 0, 0]; + const dfs = (x, d) => { + maxDepth = Math.max(maxDepth, d); + if (x.isInteger()) { + ws += x.getInteger() * d; + s += x.getInteger(); + } else { + for (const y of x.getList()) { + dfs(y, d + 1); } - depth = Math.max(depth, 1 + maxDepth(item.getList())); } - return depth; }; - const dfs = (nestedList, depth) => { - let depthSum = 0; - for (const item of nestedList) { - if (item.isInteger()) { - depthSum += item.getInteger() * depth; - } else { - depthSum += dfs(item.getList(), depth - 1); - } - } - return depthSum; - }; - const depth = maxDepth(nestedList); - return dfs(nestedList, depth); + for (const x of nestedList) { + dfs(x, 1); + } + return (maxDepth + 1) * s - ws; }; ``` diff --git a/solution/0300-0399/0364.Nested List Weight Sum II/Solution.cpp b/solution/0300-0399/0364.Nested List Weight Sum II/Solution.cpp new file mode 100644 index 0000000000000..b26172214e9d3 --- /dev/null +++ b/solution/0300-0399/0364.Nested List Weight Sum II/Solution.cpp @@ -0,0 +1,50 @@ +/** + * // This is the interface that allows for creating nested lists. + * // You should not implement it, or speculate about its implementation + * class NestedInteger { + * public: + * // Constructor initializes an empty nested list. + * NestedInteger(); + * + * // Constructor initializes a single integer. + * NestedInteger(int value); + * + * // Return true if this NestedInteger holds a single integer, rather than a nested list. + * bool isInteger() const; + * + * // Return the single integer that this NestedInteger holds, if it holds a single integer + * // The result is undefined if this NestedInteger holds a nested list + * int getInteger() const; + * + * // Set this NestedInteger to hold a single integer. + * void setInteger(int value); + * + * // Set this NestedInteger to hold a nested list and adds a nested integer to it. + * void add(const NestedInteger &ni); + * + * // Return the nested list that this NestedInteger holds, if it holds a nested list + * // The result is undefined if this NestedInteger holds a single integer + * const vector &getList() const; + * }; + */ +class Solution { +public: + int depthSumInverse(vector& nestedList) { + int maxDepth = 0, ws = 0, s = 0; + function dfs = [&](NestedInteger& x, int d) { + maxDepth = max(maxDepth, d); + if (x.isInteger()) { + ws += x.getInteger() * d; + s += x.getInteger(); + } else { + for (auto& y : x.getList()) { + dfs(y, d + 1); + } + } + }; + for (auto& x : nestedList) { + dfs(x, 1); + } + return (maxDepth + 1) * s - ws; + } +}; \ No newline at end of file diff --git a/solution/0300-0399/0364.Nested List Weight Sum II/Solution.go b/solution/0300-0399/0364.Nested List Weight Sum II/Solution.go new file mode 100644 index 0000000000000..7133b7d92e51d --- /dev/null +++ b/solution/0300-0399/0364.Nested List Weight Sum II/Solution.go @@ -0,0 +1,44 @@ +/** + * // This is the interface that allows for creating nested lists. + * // You should not implement it, or speculate about its implementation + * type NestedInteger struct { + * } + * + * // Return true if this NestedInteger holds a single integer, rather than a nested list. + * func (n NestedInteger) IsInteger() bool {} + * + * // Return the single integer that this NestedInteger holds, if it holds a single integer + * // The result is undefined if this NestedInteger holds a nested list + * // So before calling this method, you should have a check + * func (n NestedInteger) GetInteger() int {} + * + * // Set this NestedInteger to hold a single integer. + * func (n *NestedInteger) SetInteger(value int) {} + * + * // Set this NestedInteger to hold a nested list and adds a nested integer to it. + * func (n *NestedInteger) Add(elem NestedInteger) {} + * + * // Return the nested list that this NestedInteger holds, if it holds a nested list + * // The list length is zero if this NestedInteger holds a single integer + * // You can access NestedInteger's List element directly if you want to modify it + * func (n NestedInteger) GetList() []*NestedInteger {} + */ +func depthSumInverse(nestedList []*NestedInteger) int { + var maxDepth, ws, s int + var dfs func(*NestedInteger, int) + dfs = func(x *NestedInteger, d int) { + maxDepth = max(maxDepth, d) + if x.IsInteger() { + ws += x.GetInteger() * d + s += x.GetInteger() + } else { + for _, y := range x.GetList() { + dfs(y, d+1) + } + } + } + for _, x := range nestedList { + dfs(x, 1) + } + return (maxDepth+1)*s - ws +} \ No newline at end of file diff --git a/solution/0300-0399/0364.Nested List Weight Sum II/Solution.java b/solution/0300-0399/0364.Nested List Weight Sum II/Solution.java index 285369a38cbc8..c81571a396d09 100644 --- a/solution/0300-0399/0364.Nested List Weight Sum II/Solution.java +++ b/solution/0300-0399/0364.Nested List Weight Sum II/Solution.java @@ -27,31 +27,26 @@ * } */ class Solution { - public int depthSumInverse(List nestedList) { - int depth = maxDepth(nestedList); - return dfs(nestedList, depth); - } + private int maxDepth; + private int ws; + private int s; - private int maxDepth(List nestedList) { - int depth = 1; - for (NestedInteger item : nestedList) { - if (item.isInteger()) { - continue; - } - depth = Math.max(depth, 1 + maxDepth(item.getList())); + public int depthSumInverse(List nestedList) { + for (NestedInteger x : nestedList) { + dfs(x, 1); } - return depth; + return (maxDepth + 1) * s - ws; } - private int dfs(List nestedList, int depth) { - int depthSum = 0; - for (NestedInteger item : nestedList) { - if (item.isInteger()) { - depthSum += item.getInteger() * depth; - } else { - depthSum += dfs(item.getList(), depth - 1); + private void dfs(NestedInteger x, int d) { + maxDepth = Math.max(maxDepth, d); + if (x.isInteger()) { + ws += x.getInteger() * d; + s += x.getInteger(); + } else { + for (NestedInteger y : x.getList()) { + dfs(y, d + 1); } } - return depthSum; } } \ No newline at end of file diff --git a/solution/0300-0399/0364.Nested List Weight Sum II/Solution.js b/solution/0300-0399/0364.Nested List Weight Sum II/Solution.js index ce6be40227d42..d8c97ba5d60bd 100644 --- a/solution/0300-0399/0364.Nested List Weight Sum II/Solution.js +++ b/solution/0300-0399/0364.Nested List Weight Sum II/Solution.js @@ -41,27 +41,20 @@ * @return {number} */ var depthSumInverse = function (nestedList) { - const maxDepth = nestedList => { - let depth = 1; - for (const item of nestedList) { - if (item.isInteger()) { - continue; + let [maxDepth, ws, s] = [0, 0, 0]; + const dfs = (x, d) => { + maxDepth = Math.max(maxDepth, d); + if (x.isInteger()) { + ws += x.getInteger() * d; + s += x.getInteger(); + } else { + for (const y of x.getList()) { + dfs(y, d + 1); } - depth = Math.max(depth, 1 + maxDepth(item.getList())); } - return depth; }; - const dfs = (nestedList, depth) => { - let depthSum = 0; - for (const item of nestedList) { - if (item.isInteger()) { - depthSum += item.getInteger() * depth; - } else { - depthSum += dfs(item.getList(), depth - 1); - } - } - return depthSum; - }; - const depth = maxDepth(nestedList); - return dfs(nestedList, depth); + for (const x of nestedList) { + dfs(x, 1); + } + return (maxDepth + 1) * s - ws; }; diff --git a/solution/0300-0399/0364.Nested List Weight Sum II/Solution.py b/solution/0300-0399/0364.Nested List Weight Sum II/Solution.py index 2a2c7f7597b15..947f9d772760e 100644 --- a/solution/0300-0399/0364.Nested List Weight Sum II/Solution.py +++ b/solution/0300-0399/0364.Nested List Weight Sum II/Solution.py @@ -42,22 +42,17 @@ # """ class Solution: def depthSumInverse(self, nestedList: List[NestedInteger]) -> int: - def max_depth(nestedList): - depth = 1 - for item in nestedList: - if item.isInteger(): - continue - depth = max(depth, max_depth(item.getList()) + 1) - return depth + def dfs(x, d): + nonlocal maxDepth, s, ws + maxDepth = max(maxDepth, d) + if x.isInteger(): + s += x.getInteger() + ws += x.getInteger() * d + else: + for y in x.getList(): + dfs(y, d + 1) - def dfs(nestedList, max_depth): - depth_sum = 0 - for item in nestedList: - if item.isInteger(): - depth_sum += item.getInteger() * max_depth - else: - depth_sum += dfs(item.getList(), max_depth - 1) - return depth_sum - - depth = max_depth(nestedList) - return dfs(nestedList, depth) + maxDepth = s = ws = 0 + for x in nestedList: + dfs(x, 1) + return (maxDepth + 1) * s - ws diff --git a/solution/0300-0399/0364.Nested List Weight Sum II/Solution.ts b/solution/0300-0399/0364.Nested List Weight Sum II/Solution.ts new file mode 100644 index 0000000000000..984c0c1b7cead --- /dev/null +++ b/solution/0300-0399/0364.Nested List Weight Sum II/Solution.ts @@ -0,0 +1,57 @@ +/** + * // This is the interface that allows for creating nested lists. + * // You should not implement it, or speculate about its implementation + * class NestedInteger { + * If value is provided, then it holds a single integer + * Otherwise it holds an empty nested list + * constructor(value?: number) { + * ... + * }; + * + * Return true if this NestedInteger holds a single integer, rather than a nested list. + * isInteger(): boolean { + * ... + * }; + * + * Return the single integer that this NestedInteger holds, if it holds a single integer + * Return null if this NestedInteger holds a nested list + * getInteger(): number | null { + * ... + * }; + * + * Set this NestedInteger to hold a single integer equal to value. + * setInteger(value: number) { + * ... + * }; + * + * Set this NestedInteger to hold a nested list and adds a nested integer elem to it. + * add(elem: NestedInteger) { + * ... + * }; + * + * Return the nested list that this NestedInteger holds, + * or an empty list if this NestedInteger holds a single integer + * getList(): NestedInteger[] { + * ... + * }; + * }; + */ + +function depthSumInverse(nestedList: NestedInteger[]): number { + let [maxDepth, ws, s] = [0, 0, 0]; + const dfs = (x: NestedInteger, d: number) => { + maxDepth = Math.max(maxDepth, d); + if (x.isInteger()) { + ws += x.getInteger() * d; + s += x.getInteger(); + } else { + for (const y of x.getList()) { + dfs(y, d + 1); + } + } + }; + for (const x of nestedList) { + dfs(x, 1); + } + return (maxDepth + 1) * s - ws; +} diff --git a/solution/0300-0399/0365.Water and Jug Problem/README.md b/solution/0300-0399/0365.Water and Jug Problem/README.md index 34a6f348b1e28..47f5ea7fa8c23 100644 --- a/solution/0300-0399/0365.Water and Jug Problem/README.md +++ b/solution/0300-0399/0365.Water and Jug Problem/README.md @@ -76,7 +76,7 @@ tags: ### 方法一:DFS -我们不妨记 $jug1Capacity$ 为 $x$, $jug2Capacity$ 为 $y$, $targetCapacity$ 为 $z$。 +我们不妨记 $\text{jug1Capacity}$ 为 $x$, $\text{jug2Capacity}$ 为 $y$, $\text{targetCapacity}$ 为 $z$。 接下来,我们设计一个函数 $dfs(i, j)$,表示当前 $jug1$ 中有 $i$ 升水,$jug2$ 中有 $j$ 升水,是否可以得到 $z$ 升水。 @@ -89,7 +89,7 @@ tags: 答案即为 $dfs(0, 0)$。 -时间复杂度 $O(x + y)$,空间复杂度 $O(x + y)$。其中 $x$ 和 $y$ 分别为 $jug1Capacity$ 和 $jug2Capacity$ 的大小。 +时间复杂度 $O(x + y)$,空间复杂度 $O(x + y)$。其中 $x$ 和 $y$ 分别为 $\text{jug1Capacity}$ 和 $\text{jug2Capacity}$。