feat: add solutions to lc problems: No.362,364 (#2968)

* No.0362.Design Hit Counter
* No.0364.Nested List Weight Sum II
This commit is contained in:
Libin YANG 2024-05-30 20:58:16 +08:00 committed by GitHub
parent ff06d9e579
commit fa64f16eb7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 1091 additions and 343 deletions

View File

@ -71,8 +71,6 @@ for (int i = n / 2; i > 0; --i) {
<!-- tabs:start -->
### **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

View File

@ -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
}
}

View File

@ -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..<n {
ans[i] = left
left *= a[i]
}
var right = 1
for i in (0..<n).reversed() {
ans[i] *= right
right *= a[i]
}
return ans
}
}

View File

@ -189,22 +189,22 @@ class Solution {
var result = ""
var carry = 0
var i = a.count - 1, j = b.count - 1
let aChars = Array(a)
let bChars = Array(b)
while i >= 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
}
}

View File

@ -74,7 +74,11 @@ counter.getHits(301); // 在时刻 301 统计过去 5 分钟内的敲击次数
<!-- solution:start -->
### 方法一
### 方法一:二分查找
由于 `timestamp` 是单调递增的,我们可以使用一个数组 `ts` 来存储所有的 `timestamp`,然后在 `getHits` 方法中使用二分查找找到第一个大于等于 `timestamp - 300 + 1` 的位置,然后返回 `ts` 的长度减去这个位置即可。
时间复杂度方面,`hit` 方法的时间复杂度为 $O(1)$`getHits` 方法的时间复杂度为 $O(\log n)$。其中 $n$ 为 `ts` 的长度。
<!-- tabs:start -->
@ -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<Integer> ts = new ArrayList<>();
private Map<Integer, Integer> 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<Integer, Integer> 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<int> 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<Reverse<i32>>,
ts: Vec<i32>,
}
/**
* `&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);
*/
```
<!-- tabs:end -->

View File

@ -71,7 +71,11 @@ hitCounter.getHits(301); // get hits at timestamp 301, return 3.
<!-- solution:start -->
### 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`.
<!-- tabs:start -->
@ -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<Integer> ts = new ArrayList<>();
private Map<Integer, Integer> 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<Integer, Integer> 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<int> 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<Reverse<i32>>,
ts: Vec<i32>,
}
/**
* `&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);
*/
```
<!-- tabs:end -->

View File

@ -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<int> ts;
};
/**
* Your HitCounter object will be instantiated and called as such:
* HitCounter* obj = new HitCounter();
* obj->hit(timestamp);
* int param_2 = obj->getHits(timestamp);
*/

View File

@ -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);
*/

View File

@ -1,32 +1,29 @@
class HitCounter {
private List<Integer> ts = new ArrayList<>();
private Map<Integer, Integer> 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<Integer, Integer> 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;
}
}

View File

@ -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:

View File

@ -1,30 +1,40 @@
use std::{ collections::BinaryHeap, cmp::Reverse };
struct HitCounter {
/// A min heap
pq: BinaryHeap<Reverse<i32>>,
ts: Vec<i32>,
}
/**
* `&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);
*/

View File

@ -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)
*/

View File

@ -60,7 +60,13 @@ tags:
<!-- solution:start -->
### 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)$.
<!-- tabs:start -->

View File

@ -62,7 +62,35 @@ tags:
<!-- solution:start -->
### 方法一
### 方法一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$ 为整数的个数。
<!-- tabs:start -->
@ -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(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
```
#### Java
@ -166,33 +189,194 @@ class Solution:
* }
*/
class Solution {
private int maxDepth;
private int ws;
private int s;
public int depthSumInverse(List<NestedInteger> nestedList) {
int depth = maxDepth(nestedList);
return dfs(nestedList, depth);
}
private int maxDepth(List<NestedInteger> nestedList) {
int depth = 1;
for (NestedInteger item : nestedList) {
if (item.isInteger()) {
continue;
}
depth = Math.max(depth, 1 + maxDepth(item.getList()));
for (NestedInteger x : nestedList) {
dfs(x, 1);
}
return depth;
return (maxDepth + 1) * s - ws;
}
private int dfs(List<NestedInteger> nestedList, int depth) {
int depthSum = 0;
for (NestedInteger item : nestedList) {
if (item.isInteger()) {
depthSum += item.getInteger() * depth;
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);
}
}
}
}
```
#### 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<NestedInteger> &getList() const;
* };
*/
class Solution {
public:
int depthSumInverse(vector<NestedInteger>& nestedList) {
int maxDepth = 0, ws = 0, s = 0;
function<void(NestedInteger&, int)> 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;
}
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);
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);
}
}
return depthSum;
};
const depth = maxDepth(nestedList);
return dfs(nestedList, depth);
for (const x of nestedList) {
dfs(x, 1);
}
return (maxDepth + 1) * s - ws;
};
```

View File

@ -60,7 +60,35 @@ tags:
<!-- solution:start -->
### 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.
<!-- tabs:start -->
@ -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(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
```
#### Java
@ -164,33 +187,194 @@ class Solution:
* }
*/
class Solution {
private int maxDepth;
private int ws;
private int s;
public int depthSumInverse(List<NestedInteger> nestedList) {
int depth = maxDepth(nestedList);
return dfs(nestedList, depth);
}
private int maxDepth(List<NestedInteger> nestedList) {
int depth = 1;
for (NestedInteger item : nestedList) {
if (item.isInteger()) {
continue;
}
depth = Math.max(depth, 1 + maxDepth(item.getList()));
for (NestedInteger x : nestedList) {
dfs(x, 1);
}
return depth;
return (maxDepth + 1) * s - ws;
}
private int dfs(List<NestedInteger> nestedList, int depth) {
int depthSum = 0;
for (NestedInteger item : nestedList) {
if (item.isInteger()) {
depthSum += item.getInteger() * depth;
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);
}
}
}
}
```
#### 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<NestedInteger> &getList() const;
* };
*/
class Solution {
public:
int depthSumInverse(vector<NestedInteger>& nestedList) {
int maxDepth = 0, ws = 0, s = 0;
function<void(NestedInteger&, int)> 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;
}
```
@ -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;
}
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);
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);
}
}
return depthSum;
};
const depth = maxDepth(nestedList);
return dfs(nestedList, depth);
for (const x of nestedList) {
dfs(x, 1);
}
return (maxDepth + 1) * s - ws;
};
```

View File

@ -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<NestedInteger> &getList() const;
* };
*/
class Solution {
public:
int depthSumInverse(vector<NestedInteger>& nestedList) {
int maxDepth = 0, ws = 0, s = 0;
function<void(NestedInteger&, int)> 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;
}
};

View File

@ -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
}

View File

@ -27,31 +27,26 @@
* }
*/
class Solution {
private int maxDepth;
private int ws;
private int s;
public int depthSumInverse(List<NestedInteger> 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<NestedInteger> nestedList) {
int depth = 1;
for (NestedInteger item : nestedList) {
if (item.isInteger()) {
continue;
}
depth = Math.max(depth, 1 + maxDepth(item.getList()));
}
return depth;
}
private int dfs(List<NestedInteger> 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;
}
}

View File

@ -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;
}
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);
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);
}
}
return depthSum;
};
const depth = maxDepth(nestedList);
return dfs(nestedList, depth);
for (const x of nestedList) {
dfs(x, 1);
}
return (maxDepth + 1) * s - ws;
};

View File

@ -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

View File

@ -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;
}

View File

@ -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}$。
<!-- tabs:start -->