Skip to content

Commit dad4db8

Browse files
authored
Added tasks 357, 363.
1 parent 42af7df commit dad4db8

File tree

6 files changed

+240
-0
lines changed

6 files changed

+240
-0
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package g0301_0400.s0357_count_numbers_with_unique_digits;
2+
3+
// #Medium #Dynamic_Programming #Math #Backtracking
4+
5+
public class Solution {
6+
public int countNumbersWithUniqueDigits(int n) {
7+
int ans = 1;
8+
for (int i = 1; i <= n; i++) {
9+
int mul = 1;
10+
for (int j = 1; j < i; j++) {
11+
mul *= (10 - j);
12+
}
13+
ans = ans + 9 * mul;
14+
}
15+
return ans;
16+
}
17+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
357\. Count Numbers with Unique Digits
2+
3+
Medium
4+
5+
Given an integer `n`, return the count of all numbers with unique digits, `x`, where <code>0 <= x < 10<sup>n</sup></code>.
6+
7+
**Example 1:**
8+
9+
**Input:** n = 2
10+
11+
**Output:** 91
12+
13+
**Explanation:** The answer should be the total numbers in the range of 0 ≤ x < 100, excluding 11,22,33,44,55,66,77,88,99
14+
15+
**Example 2:**
16+
17+
**Input:** n = 0
18+
19+
**Output:** 1
20+
21+
**Constraints:**
22+
23+
* `0 <= n <= 8`
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
package g0301_0400.s0363_max_sum_of_rectangle_no_larger_than_k;
2+
3+
// #Hard #Array #Dynamic_Programming #Binary_Search #Matrix #Ordered_Set
4+
5+
/*
6+
*
7+
* Basic idea is the same as previous approach but we solve the problem in Step 2 differently.
8+
* Here we leverage divide and conquer technique. Basically we perform merge sort on prefix sum values and
9+
* calculate result during merge step.
10+
* One might remember the idea of using merge sort to count inversions in an array. This is very similar.
11+
12+
* So how exactly do we compute result during merge step?
13+
* Suppose we are merging left prefix subarray and right prefix subarray.
14+
* Remember from previous approach, for each index we're trying to find an old prefix sum which is just greater than or
15+
* equal to current prefix sum - k.
16+
* So we can iterate over right subarray and for each index j, keep incrementing the pointer
17+
* in left array i (initialized to start index) till that situation is false (or basically prefix[i] < prefix[j] - k).
18+
* This way, we can compute the result for all cross subarrays (i.e. i in left subarray and j in right subarray)
19+
* in linear time.
20+
* After this, we do the standard merging part of merge sort.
21+
*
22+
*/
23+
24+
import java.util.Arrays;
25+
26+
public class Solution {
27+
private int[] m;
28+
29+
private int merge(int[] a, int l, int m, int r, int k) {
30+
int res = Integer.MIN_VALUE;
31+
for (int j = m + 1; j <= r; j++) {
32+
int i = l;
33+
while (i <= m && a[j] - a[i] > k) {
34+
i++;
35+
}
36+
if (i > m) {
37+
break;
38+
}
39+
res = Math.max(res, a[j] - a[i]);
40+
if (res == k) {
41+
return res;
42+
}
43+
}
44+
int i = l;
45+
int j = m + 1;
46+
int t = 0;
47+
while (i <= m && j <= r) {
48+
this.m[t++] = a[i] <= a[j] ? a[i++] : a[j++];
49+
}
50+
while (i <= m) {
51+
this.m[t++] = a[i++];
52+
}
53+
while (j <= r) {
54+
this.m[t++] = a[j++];
55+
}
56+
for (i = l; i <= r; i++) {
57+
a[i] = this.m[i - l];
58+
}
59+
return res;
60+
}
61+
62+
private int mergeSort(int[] a, int l, int r, int k) {
63+
if (l == r) {
64+
return a[l] <= k ? a[l] : Integer.MIN_VALUE;
65+
}
66+
int localM = l + ((r - l) >> 1);
67+
int res = mergeSort(a, l, localM, k);
68+
if (res == k) {
69+
return res;
70+
}
71+
res = Math.max(res, mergeSort(a, localM + 1, r, k));
72+
if (res == k) {
73+
return res;
74+
}
75+
return Math.max(res, merge(a, l, localM, r, k));
76+
}
77+
78+
private int maxSumSubArray(int[] a) {
79+
int min = 0;
80+
int res = Integer.MIN_VALUE;
81+
for (int sum : a) {
82+
res = Math.max(res, sum - min);
83+
min = Math.min(min, sum);
84+
}
85+
return res;
86+
}
87+
88+
private int maxSumSubArray(int[] a, int k) {
89+
int res = maxSumSubArray(a);
90+
if (res <= k) {
91+
return res;
92+
}
93+
return mergeSort(a.clone(), 0, a.length - 1, k);
94+
}
95+
96+
public int maxSumSubMatrix(int[][] matrix, int k) {
97+
int localM = matrix.length;
98+
int localN = localM == 0 ? 0 : matrix[0].length;
99+
int res = Integer.MIN_VALUE;
100+
boolean groupingRows = true;
101+
if (localM > localN) {
102+
int temp = localM;
103+
localM = localN;
104+
localN = temp;
105+
groupingRows = false;
106+
}
107+
int[] sum = new int[localN];
108+
this.m = new int[localN];
109+
for (int i = 0; i < localM; i++) {
110+
Arrays.fill(sum, 0);
111+
for (int j = i; j < localM; j++) {
112+
int pre = 0;
113+
if (groupingRows) {
114+
for (int t = 0; t < localN; t++) {
115+
sum[t] += pre += matrix[j][t];
116+
}
117+
} else {
118+
for (int t = 0; t < localN; t++) {
119+
sum[t] += pre += matrix[t][j];
120+
}
121+
}
122+
res = Math.max(res, maxSumSubArray(sum, k));
123+
if (res == k) {
124+
return res;
125+
}
126+
}
127+
}
128+
return res;
129+
}
130+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
363. Max Sum of Rectangle No Larger Than K
2+
3+
Hard
4+
5+
Given an `m x n` matrix `matrix` and an integer `k`, return _the max sum of a rectangle in the matrix such that its sum is no larger than_ `k`.
6+
7+
It is **guaranteed** that there will be a rectangle with a sum no larger than `k`.
8+
9+
**Example 1:**
10+
11+
![](https://assets.leetcode.com/uploads/2021/03/18/sum-grid.jpg)
12+
13+
**Input:** matrix = [[1,0,1],[0,-2,3]], k = 2
14+
15+
**Output:** 2
16+
17+
**Explanation:** Because the sum of the blue rectangle [[0, 1], [-2, 3]] is 2, and 2 is the max number no larger than k (k = 2).
18+
19+
**Example 2:**
20+
21+
**Input:** matrix = [[2,2,-1]], k = 3
22+
23+
**Output:** 3
24+
25+
**Constraints:**
26+
27+
* `m == matrix.length`
28+
* `n == matrix[i].length`
29+
* `1 <= m, n <= 100`
30+
* `-100 <= matrix[i][j] <= 100`
31+
* <code>-10<sup>5</sup> <= k <= 10<sup>5</sup></code>
32+
33+
**Follow up:** What if the number of rows is much larger than the number of columns?
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package g0301_0400.s0357_count_numbers_with_unique_digits;
2+
3+
import static org.hamcrest.CoreMatchers.equalTo;
4+
import static org.hamcrest.MatcherAssert.assertThat;
5+
6+
import org.junit.jupiter.api.Test;
7+
8+
class SolutionTest {
9+
@Test
10+
void countNumbersWithUniqueDigits() {
11+
assertThat(new Solution().countNumbersWithUniqueDigits(2), equalTo(91));
12+
}
13+
14+
@Test
15+
void countNumbersWithUniqueDigits2() {
16+
assertThat(new Solution().countNumbersWithUniqueDigits(0), equalTo(1));
17+
}
18+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package g0301_0400.s0363_max_sum_of_rectangle_no_larger_than_k;
2+
3+
import static org.hamcrest.CoreMatchers.equalTo;
4+
import static org.hamcrest.MatcherAssert.assertThat;
5+
6+
import org.junit.jupiter.api.Test;
7+
8+
class SolutionTest {
9+
@Test
10+
void maxSumSubMatrix() {
11+
assertThat(
12+
new Solution().maxSumSubMatrix(new int[][] {{1, 0, 1}, {0, -2, 3}}, 2), equalTo(2));
13+
}
14+
15+
@Test
16+
void maxSumSubMatrix2() {
17+
assertThat(new Solution().maxSumSubMatrix(new int[][] {{2, 2, -1}}, 3), equalTo(3));
18+
}
19+
}

0 commit comments

Comments
 (0)