Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit fdabd5f

Browse files
committed
feat: add solutions to lc problem: No.0673
No.0673.Number of Longest Increasing Subsequence
1 parent c6502f5 commit fdabd5f

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‎

Lines changed: 337 additions & 205 deletions
Large diffs are not rendered by default.

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

Lines changed: 344 additions & 195 deletions
Large diffs are not rendered by default.
Lines changed: 56 additions & 26 deletions
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+
};
Lines changed: 49 additions & 20 deletions
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
}
Lines changed: 55 additions & 28 deletions
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+
}
Lines changed: 39 additions & 18 deletions
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]
Lines changed: 52 additions & 21 deletions
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)

AltStyle によって変換されたページ (->オリジナル) /