Skip to content

feat: add solutions to lc problems: No.2397,2487,2980+ #2174

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@

**方法一:二进制枚举**

我们先将矩阵中的每一行转换成一个二进制数,记录在数组 $rows$ 中,其中 $rows[i]$ 表示第 $i$ 行对应的二进制数,而 $rows[i]$ 的第 $j$ 位表示第 $i$ 行第 $j$ 列的值。
我们先将矩阵中的每一行转换成一个二进制数,记录在数组 $rows$ 中,其中 $rows[i]$ 表示第 $i$ 行对应的二进制数,而 $rows[i]$ 这个二进制数的第 $j$ 位表示第 $i$ 行第 $j$ 列的值。

接下来,我们枚举所有的 $2^n$ 种列选择方案,其中 $n$ 为矩阵的列数。对于每一种列选择方案,我们判断是否选中了 `numSelect` 列,如果不是,则跳过。否则,我们统计矩阵中有多少行中的所有 $1$ 都被选中的列覆盖,即统计有多少行的二进制数 $rows[i]$ 与列选择方案 $mask$ 按位与的结果等于 $rows[i]$,并更新最大的行数。

Expand Down Expand Up @@ -199,7 +199,40 @@ func maximumRows(matrix [][]int, numSelect int) (ans int) {
### **TypeScript**

```ts
function maximumRows(matrix: number[][], numSelect: number): number {
const [m, n] = [matrix.length, matrix[0].length];
const rows: number[] = Array(m).fill(0);
for (let i = 0; i < m; ++i) {
for (let j = 0; j < n; ++j) {
if (matrix[i][j]) {
rows[i] |= 1 << j;
}
}
}
let ans = 0;
for (let mask = 1; mask < 1 << n; ++mask) {
if (bitCount(mask) !== numSelect) {
continue;
}
let t = 0;
for (const x of rows) {
if ((x & mask) === x) {
++t;
}
}
ans = Math.max(ans, t);
}
return ans;
}

function bitCount(i: number): number {
i = i - ((i >>> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
i = (i + (i >>> 4)) & 0x0f0f0f0f;
i = i + (i >>> 8);
i = i + (i >>> 16);
return i & 0x3f;
}
```

### **...**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@ Therefore, we return 2.

## Solutions

**Solution 1: Binary Enumeration**

First, we convert each row of the matrix into a binary number and record it in the array $rows$. Here, $rows[i]$ represents the binary number corresponding to the $i$-th row, and the $j$-th bit of this binary number $rows[i]$ represents the value of the $i$-th row and $j$-th column.

Next, we enumerate all $2^n$ column selection schemes, where $n$ is the number of columns in the matrix. For each column selection scheme, we check whether `numSelect` columns have been selected. If not, we skip it. Otherwise, we count how many rows in the matrix are covered by the selected columns, i.e., how many binary numbers $rows[i]$ are equal to the bitwise AND of $rows[i]$ and the column selection scheme $mask$. We then update the maximum number of rows.

The time complexity is $O(2^n \times m)$, and the space complexity is $O(m)$. Where $m$ and $n$ are the number of rows and columns in the matrix, respectively.

<!-- tabs:start -->

### **Python3**
Expand Down Expand Up @@ -174,7 +182,40 @@ func maximumRows(matrix [][]int, numSelect int) (ans int) {
### **TypeScript**

```ts
function maximumRows(matrix: number[][], numSelect: number): number {
const [m, n] = [matrix.length, matrix[0].length];
const rows: number[] = Array(m).fill(0);
for (let i = 0; i < m; ++i) {
for (let j = 0; j < n; ++j) {
if (matrix[i][j]) {
rows[i] |= 1 << j;
}
}
}
let ans = 0;
for (let mask = 1; mask < 1 << n; ++mask) {
if (bitCount(mask) !== numSelect) {
continue;
}
let t = 0;
for (const x of rows) {
if ((x & mask) === x) {
++t;
}
}
ans = Math.max(ans, t);
}
return ans;
}

function bitCount(i: number): number {
i = i - ((i >>> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
i = (i + (i >>> 4)) & 0x0f0f0f0f;
i = i + (i >>> 8);
i = i + (i >>> 16);
return i & 0x3f;
}
```

### **...**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
function maximumRows(matrix: number[][], numSelect: number): number {
const [m, n] = [matrix.length, matrix[0].length];
const rows: number[] = Array(m).fill(0);
for (let i = 0; i < m; ++i) {
for (let j = 0; j < n; ++j) {
if (matrix[i][j]) {
rows[i] |= 1 << j;
}
}
}
let ans = 0;
for (let mask = 1; mask < 1 << n; ++mask) {
if (bitCount(mask) !== numSelect) {
continue;
}
let t = 0;
for (const x of rows) {
if ((x & mask) === x) {
++t;
}
}
ans = Math.max(ans, t);
}
return ans;
}

function bitCount(i: number): number {
i = i - ((i >>> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
i = (i + (i >>> 4)) & 0x0f0f0f0f;
i = i + (i >>> 8);
i = i + (i >>> 16);
return i & 0x3f;
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
class Solution:
def maximumRobots(
self, chargeTimes: List[int], runningCosts: List[int], budget: int
) -> int:
q = deque()
ans = j = s = 0
for i, (a, b) in enumerate(zip(chargeTimes, runningCosts)):
while q and chargeTimes[q[-1]] <= a:
q.pop()
q.append(i)
s += b
while q and chargeTimes[q[0]] + (i - j + 1) * s > budget:
if q[0] == j:
q.popleft()
s -= runningCosts[j]
j += 1
ans = max(ans, i - j + 1)
return ans
class Solution:
def maximumRobots(
self, chargeTimes: List[int], runningCosts: List[int], budget: int
) -> int:
q = deque()
ans = j = s = 0
for i, (a, b) in enumerate(zip(chargeTimes, runningCosts)):
while q and chargeTimes[q[-1]] <= a:
q.pop()
q.append(i)
s += b
while q and chargeTimes[q[0]] + (i - j + 1) * s > budget:
if q[0] == j:
q.popleft()
s -= runningCosts[j]
j += 1
ans = max(ans, i - j + 1)
return ans
51 changes: 45 additions & 6 deletions solution/2400-2499/2487.Remove Nodes From Linked List/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,11 @@

**方法一:单调栈模拟**

我们可以先将链表中的节点值存入数组,然后遍历数组,维护一个从栈底到栈顶单调递减的栈,如果当前元素比栈顶元素大,则将栈顶元素出栈,直到当前元素小于等于栈顶元素,将当前元素入栈。最后将栈中的元素逆序,构造得到的链表即为答案
我们可以先将链表中的节点值存入数组 $nums$,然后遍历数组 $nums$,维护一个从栈底到栈顶单调递减的栈 $stk$,如果当前元素比栈顶元素大,则将栈顶元素出栈,直到当前元素小于等于栈顶元素,将当前元素入栈。

时间复杂度为 $O(n)$,空间复杂度为 $O(n)$。
最后,我们从栈底到栈顶构造出结果链表,即为答案。

时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是链表的长度。

<!-- tabs:start -->

Expand Down Expand Up @@ -109,15 +111,15 @@ class Solution {
}
Deque<Integer> stk = new ArrayDeque<>();
for (int v : nums) {
while (!stk.isEmpty() && stk.peek() < v) {
stk.pop();
while (!stk.isEmpty() && stk.peekLast() < v) {
stk.pollLast();
}
stk.push(v);
stk.offerLast(v);
}
ListNode dummy = new ListNode();
head = dummy;
while (!stk.isEmpty()) {
head.next = new ListNode(stk.pollLast());
head.next = new ListNode(stk.pollFirst());
head = head.next;
}
return dummy.next;
Expand Down Expand Up @@ -197,6 +199,43 @@ func removeNodes(head *ListNode) *ListNode {
}
```

### **TypeScript**

```ts
/**
* Definition for singly-linked list.
* class ListNode {
* val: number
* next: ListNode | null
* constructor(val?: number, next?: ListNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
* }
*/

function removeNodes(head: ListNode | null): ListNode | null {
const nums = [];
for (; head; head = head.next) {
nums.push(head.val);
}
const stk: number[] = [];
for (const v of nums) {
while (stk.length && stk.at(-1)! < v) {
stk.pop();
}
stk.push(v);
}
const dummy = new ListNode();
head = dummy;
for (const v of stk) {
head.next = new ListNode(v);
head = head.next;
}
return dummy.next;
}
```

### **...**

```
Expand Down
53 changes: 49 additions & 4 deletions solution/2400-2499/2487.Remove Nodes From Linked List/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@

## Solutions

**Solution 1: Monotonic Stack Simulation**

We can first store the node values of the linked list into an array $nums$. Then, we traverse the array $nums$, maintaining a stack $stk$ that is monotonically decreasing from the bottom to the top. If the current element is larger than the top element of the stack, we pop the top element of the stack until the current element is less than or equal to the top element, and then we push the current element into the stack.

Finally, we construct the resulting linked list from the bottom to the top of the stack, which is the answer.

The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the linked list.

<!-- tabs:start -->

### **Python3**
Expand Down Expand Up @@ -91,15 +99,15 @@ class Solution {
}
Deque<Integer> stk = new ArrayDeque<>();
for (int v : nums) {
while (!stk.isEmpty() && stk.peek() < v) {
stk.pop();
while (!stk.isEmpty() && stk.peekLast() < v) {
stk.pollLast();
}
stk.push(v);
stk.offerLast(v);
}
ListNode dummy = new ListNode();
head = dummy;
while (!stk.isEmpty()) {
head.next = new ListNode(stk.pollLast());
head.next = new ListNode(stk.pollFirst());
head = head.next;
}
return dummy.next;
Expand Down Expand Up @@ -179,6 +187,43 @@ func removeNodes(head *ListNode) *ListNode {
}
```

### **TypeScript**

```ts
/**
* Definition for singly-linked list.
* class ListNode {
* val: number
* next: ListNode | null
* constructor(val?: number, next?: ListNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
* }
*/

function removeNodes(head: ListNode | null): ListNode | null {
const nums = [];
for (; head; head = head.next) {
nums.push(head.val);
}
const stk: number[] = [];
for (const v of nums) {
while (stk.length && stk.at(-1)! < v) {
stk.pop();
}
stk.push(v);
}
const dummy = new ListNode();
head = dummy;
for (const v of stk) {
head.next = new ListNode(v);
head = head.next;
}
return dummy.next;
}
```

### **...**

```
Expand Down
Loading