Skip to content

Commit 56084a8

Browse files
authored
feat: add solutions to lc problem: No.0673 (#2048)
No.0673.Number of Longest Increasing Subsequence
1 parent c6502f5 commit 56084a8

File tree

8 files changed

+995
-513
lines changed

8 files changed

+995
-513
lines changed

solution/0600-0699/0673.Number of Longest Increasing Subsequence/README.md

+337-205
Large diffs are not rendered by default.

solution/0600-0699/0673.Number of Longest Increasing Subsequence/README_EN.md

+344-195
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,56 @@
1-
class Solution {
2-
public:
3-
int findNumberOfLIS(vector<int>& nums) {
4-
int maxLen = 0, ans = 0, n = nums.size();
5-
vector<int> dp(n, 1), cnt(n, 1);
6-
for (int i = 0; i < n; ++i) {
7-
for (int j = 0; j < i; ++j) {
8-
if (nums[i] > nums[j]) {
9-
if (dp[j] + 1 > dp[i]) {
10-
dp[i] = dp[j] + 1;
11-
cnt[i] = cnt[j];
12-
} else if (dp[j] + 1 == dp[i]) {
13-
cnt[i] += cnt[j];
14-
}
15-
}
16-
}
17-
if (dp[i] > maxLen) {
18-
maxLen = dp[i];
19-
ans = cnt[i];
20-
} else if (dp[i] == maxLen) {
21-
ans += cnt[i];
22-
}
23-
}
24-
return ans;
25-
}
26-
};
1+
class BinaryIndexedTree {
2+
private:
3+
int n;
4+
vector<int> c;
5+
vector<int> d;
6+
7+
public:
8+
BinaryIndexedTree(int n)
9+
: n(n)
10+
, c(n + 1, 0)
11+
, d(n + 1, 0) {}
12+
13+
void update(int x, int v, int cnt) {
14+
while (x <= n) {
15+
if (c[x] < v) {
16+
c[x] = v;
17+
d[x] = cnt;
18+
} else if (c[x] == v) {
19+
d[x] += cnt;
20+
}
21+
x += x & -x;
22+
}
23+
}
24+
25+
pair<int, int> query(int x) {
26+
int v = 0, cnt = 0;
27+
while (x > 0) {
28+
if (c[x] > v) {
29+
v = c[x];
30+
cnt = d[x];
31+
} else if (c[x] == v) {
32+
cnt += d[x];
33+
}
34+
x -= x & -x;
35+
}
36+
return {v, cnt};
37+
}
38+
};
39+
40+
class Solution {
41+
public:
42+
int findNumberOfLIS(vector<int>& nums) {
43+
vector<int> arr = nums;
44+
sort(arr.begin(), arr.end());
45+
arr.erase(unique(arr.begin(), arr.end()), arr.end());
46+
int m = arr.size();
47+
BinaryIndexedTree tree(m);
48+
for (int x : nums) {
49+
auto it = lower_bound(arr.begin(), arr.end(), x);
50+
int i = distance(arr.begin(), it) + 1;
51+
auto [v, cnt] = tree.query(i - 1);
52+
tree.update(i, v + 1, max(cnt, 1));
53+
}
54+
return tree.query(m).second;
55+
}
56+
};
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,54 @@
1-
func findNumberOfLIS(nums []int) int {
2-
maxLen, ans, n := 0, 0, len(nums)
3-
dp, cnt := make([]int, n), make([]int, n)
4-
for i := 0; i < n; i++ {
5-
dp[i] = 1
6-
cnt[i] = 1
7-
for j := 0; j < i; j++ {
8-
if nums[i] > nums[j] {
9-
if dp[j]+1 > dp[i] {
10-
dp[i] = dp[j] + 1
11-
cnt[i] = cnt[j]
12-
} else if dp[j]+1 == dp[i] {
13-
cnt[i] += cnt[j]
14-
}
15-
}
1+
type BinaryIndexedTree struct {
2+
n int
3+
c []int
4+
d []int
5+
}
6+
7+
func newBinaryIndexedTree(n int) BinaryIndexedTree {
8+
return BinaryIndexedTree{
9+
n: n,
10+
c: make([]int, n+1),
11+
d: make([]int, n+1),
12+
}
13+
}
14+
15+
func (bit *BinaryIndexedTree) update(x, v, cnt int) {
16+
for x <= bit.n {
17+
if bit.c[x] < v {
18+
bit.c[x] = v
19+
bit.d[x] = cnt
20+
} else if bit.c[x] == v {
21+
bit.d[x] += cnt
1622
}
17-
if dp[i] > maxLen {
18-
maxLen = dp[i]
19-
ans = cnt[i]
20-
} else if dp[i] == maxLen {
21-
ans += cnt[i]
23+
x += x & -x
24+
}
25+
}
26+
27+
func (bit *BinaryIndexedTree) query(x int) (int, int) {
28+
v, cnt := 0, 0
29+
for x > 0 {
30+
if bit.c[x] > v {
31+
v = bit.c[x]
32+
cnt = bit.d[x]
33+
} else if bit.c[x] == v {
34+
cnt += bit.d[x]
2235
}
36+
x -= x & -x
37+
}
38+
return v, cnt
39+
}
40+
41+
func findNumberOfLIS(nums []int) int {
42+
arr := make([]int, len(nums))
43+
copy(arr, nums)
44+
sort.Ints(arr)
45+
m := len(arr)
46+
tree := newBinaryIndexedTree(m)
47+
for _, x := range nums {
48+
i := sort.SearchInts(arr, x) + 1
49+
v, cnt := tree.query(i - 1)
50+
tree.update(i, v+1, max(cnt, 1))
2351
}
52+
_, ans := tree.query(m)
2453
return ans
2554
}
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,55 @@
1-
class Solution {
2-
public int findNumberOfLIS(int[] nums) {
3-
int maxLen = 0, ans = 0, n = nums.length;
4-
int[] dp = new int[n];
5-
int[] cnt = new int[n];
6-
for (int i = 0; i < n; i++) {
7-
dp[i] = 1;
8-
cnt[i] = 1;
9-
for (int j = 0; j < i; j++) {
10-
if (nums[i] > nums[j]) {
11-
if (dp[j] + 1 > dp[i]) {
12-
dp[i] = dp[j] + 1;
13-
cnt[i] = cnt[j];
14-
} else if (dp[j] + 1 == dp[i]) {
15-
cnt[i] += cnt[j];
16-
}
17-
}
18-
}
19-
if (dp[i] > maxLen) {
20-
maxLen = dp[i];
21-
ans = cnt[i];
22-
} else if (dp[i] == maxLen) {
23-
ans += cnt[i];
24-
}
25-
}
26-
return ans;
27-
}
28-
}
1+
class BinaryIndexedTree {
2+
private int n;
3+
private int[] c;
4+
private int[] d;
5+
6+
public BinaryIndexedTree(int n) {
7+
this.n = n;
8+
c = new int[n + 1];
9+
d = new int[n + 1];
10+
}
11+
12+
public void update(int x, int v, int cnt) {
13+
while (x <= n) {
14+
if (c[x] < v) {
15+
c[x] = v;
16+
d[x] = cnt;
17+
} else if (c[x] == v) {
18+
d[x] += cnt;
19+
}
20+
x += x & -x;
21+
}
22+
}
23+
24+
public int[] query(int x) {
25+
int v = 0, cnt = 0;
26+
while (x > 0) {
27+
if (c[x] > v) {
28+
v = c[x];
29+
cnt = d[x];
30+
} else if (c[x] == v) {
31+
cnt += d[x];
32+
}
33+
x -= x & -x;
34+
}
35+
return new int[] {v, cnt};
36+
}
37+
}
38+
39+
public class Solution {
40+
public int findNumberOfLIS(int[] nums) {
41+
// int[] arr = Arrays.stream(nums).distinct().sorted().toArray();
42+
int[] arr = nums.clone();
43+
Arrays.sort(arr);
44+
int m = arr.length;
45+
BinaryIndexedTree tree = new BinaryIndexedTree(m);
46+
for (int x : nums) {
47+
int i = Arrays.binarySearch(arr, x) + 1;
48+
int[] t = tree.query(i - 1);
49+
int v = t[0];
50+
int cnt = t[1];
51+
tree.update(i, v + 1, Math.max(cnt, 1));
52+
}
53+
return tree.query(m)[1];
54+
}
55+
}
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,39 @@
1-
class Solution:
2-
def findNumberOfLIS(self, nums: List[int]) -> int:
3-
maxLen, ans, n = 0, 0, len(nums)
4-
dp, cnt = [1] * n, [1] * n
5-
for i in range(n):
6-
for j in range(i):
7-
if nums[i] > nums[j]:
8-
if dp[j] + 1 > dp[i]:
9-
dp[i] = dp[j] + 1
10-
cnt[i] = cnt[j]
11-
elif dp[j] + 1 == dp[i]:
12-
cnt[i] += cnt[j]
13-
if dp[i] > maxLen:
14-
maxLen = dp[i]
15-
ans = cnt[i]
16-
elif dp[i] == maxLen:
17-
ans += cnt[i]
18-
return ans
1+
class BinaryIndexedTree:
2+
__slots__ = ["n", "c", "d"]
3+
4+
def __init__(self, n):
5+
self.n = n
6+
self.c = [0] * (n + 1)
7+
self.d = [0] * (n + 1)
8+
9+
def update(self, x, v, cnt):
10+
while x <= self.n:
11+
if self.c[x] < v:
12+
self.c[x] = v
13+
self.d[x] = cnt
14+
elif self.c[x] == v:
15+
self.d[x] += cnt
16+
x += x & -x
17+
18+
def query(self, x):
19+
v = cnt = 0
20+
while x:
21+
if self.c[x] > v:
22+
v = self.c[x]
23+
cnt = self.d[x]
24+
elif self.c[x] == v:
25+
cnt += self.d[x]
26+
x -= x & -x
27+
return v, cnt
28+
29+
30+
class Solution:
31+
def findNumberOfLIS(self, nums: List[int]) -> int:
32+
arr = sorted(set(nums))
33+
m = len(arr)
34+
tree = BinaryIndexedTree(m)
35+
for x in nums:
36+
i = bisect_left(arr, x) + 1
37+
v, cnt = tree.query(i - 1)
38+
tree.update(i, v + 1, max(cnt, 1))
39+
return tree.query(m)[1]
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,59 @@
1+
struct BinaryIndexedTree {
2+
n: usize,
3+
c: Vec<i32>,
4+
d: Vec<i32>,
5+
}
6+
7+
impl BinaryIndexedTree {
8+
fn new(n: usize) -> BinaryIndexedTree {
9+
BinaryIndexedTree {
10+
n,
11+
c: vec![0; n + 1],
12+
d: vec![0; n + 1],
13+
}
14+
}
15+
16+
fn update(&mut self, x: usize, v: i32, cnt: i32) {
17+
let mut x = x as usize;
18+
while x <= self.n {
19+
if self.c[x] < v {
20+
self.c[x] = v;
21+
self.d[x] = cnt;
22+
} else if self.c[x] == v {
23+
self.d[x] += cnt;
24+
}
25+
x += x & x.wrapping_neg();
26+
}
27+
}
28+
29+
fn query(&self, mut x: usize) -> (i32, i32) {
30+
let (mut v, mut cnt) = (0, 0);
31+
while x > 0 {
32+
if self.c[x] > v {
33+
v = self.c[x];
34+
cnt = self.d[x];
35+
} else if self.c[x] == v {
36+
cnt += self.d[x];
37+
}
38+
x -= x & x.wrapping_neg();
39+
}
40+
(v, cnt)
41+
}
42+
}
43+
144
impl Solution {
245
pub fn find_number_of_lis(nums: Vec<i32>) -> i32 {
3-
let mut max_len = 0;
4-
let mut ans = 0;
5-
let n = nums.len();
6-
let mut dp = vec![1; n];
7-
let mut cnt = vec![1; n];
8-
for i in 0..n {
9-
for j in 0..i {
10-
if nums[i] > nums[j] {
11-
if dp[j] + 1 > dp[i] {
12-
dp[i] = dp[j] + 1;
13-
cnt[i] = cnt[j];
14-
} else if dp[j] + 1 == dp[i] {
15-
cnt[i] += cnt[j];
16-
}
17-
}
18-
}
19-
if dp[i] > max_len {
20-
max_len = dp[i];
21-
ans = cnt[i];
22-
} else if dp[i] == max_len {
23-
ans += cnt[i];
46+
let mut arr: Vec<i32> = nums.iter().cloned().collect();
47+
arr.sort();
48+
let m = arr.len();
49+
let mut tree = BinaryIndexedTree::new(m);
50+
for x in nums.iter() {
51+
if let Ok(i) = arr.binary_search(x) {
52+
let (v, cnt) = tree.query(i);
53+
tree.update(i + 1, v + 1, cnt.max(1));
2454
}
2555
}
56+
let (_, ans) = tree.query(m);
2657
ans
2758
}
2859
}

0 commit comments

Comments
 (0)