feat: add solutions to lcs problems

* No.01. 下载插件
* No.02. 完成一半题目
This commit is contained in:
yanglbme 2023-02-23 10:37:26 +08:00
parent 89f02e53fb
commit aef9e1cf09
11 changed files with 133 additions and 73 deletions

View File

@ -45,8 +45,12 @@
<!-- 这里可写通用的实现逻辑 -->
**方法一:贪心**
如果不能在一分钟内下载完,那么可以先加速,循环直至能在一分钟内下载完。那么“循环次数 + 1”即为最少消耗的分钟数。
时间复杂度 $O(\log n)$,空间复杂度 $O(1)$。其中 $n$ 为插件数量。
<!-- tabs:start -->
### **Python3**
@ -86,7 +90,9 @@ class Solution {
public:
int leastMinutes(int n) {
int ans = 1;
for (int speed = 1; speed < n; speed <<= 1) ++ans;
for (int speed = 1; speed < n; speed <<= 1) {
++ans;
}
return ans;
}
};
@ -120,6 +126,18 @@ var leastMinutes = function (n) {
};
```
### **TypeScript**
```ts
function leastMinutes(n: number): number {
let ans = 1;
for (let speed = 1; speed < n; speed <<= 1) {
++ans;
}
return ans;
}
```
### **...**
```

View File

@ -2,7 +2,9 @@ class Solution {
public:
int leastMinutes(int n) {
int ans = 1;
for (int speed = 1; speed < n; speed <<= 1) ++ans;
for (int speed = 1; speed < n; speed <<= 1) {
++ans;
}
return ans;
}
};

View File

@ -0,0 +1,7 @@
function leastMinutes(n: number): number {
let ans = 1;
for (let speed = 1; speed < n; speed <<= 1) {
++ans;
}
return ans;
}

View File

@ -36,9 +36,11 @@
<!-- 这里可写通用的实现逻辑 -->
统计各个问题类型出现的次数,按照次数降序排列。
**方法一:计数 + 排序**
然后依次选择问题类型,直至满足条件。
我们可以用哈希表或数组 `cnt` 统计每种知识点类型的题目数量,然后对 `cnt` 进行排序,从大到小遍历 `cnt`,直到遍历的题目数量之和大于等于 `n` 即可,此时遍历的次数即为所求。
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为 `questions` 的长度。
<!-- tabs:start -->
@ -49,14 +51,13 @@
```python
class Solution:
def halfQuestions(self, questions: List[int]) -> int:
counter = Counter(questions)
n = len(questions) >> 1
ans = 0
for i, v in counter.most_common():
cnt = Counter(questions)
ans, n = 0, len(questions) >> 1
for _, v in cnt.most_common():
ans += 1
if v >= n:
return ans
n -= v
if n <= 0:
break
return ans
```
@ -67,16 +68,16 @@ class Solution:
```java
class Solution {
public int halfQuestions(int[] questions) {
int[] counter = new int[1010];
for (int q : questions) {
++counter[q];
int[] cnt = new int[1010];
for (int x : questions) {
++cnt[x];
}
Arrays.sort(counter);
Arrays.sort(cnt);
int ans = 0;
int n = questions.length >> 1;
for (int i = counter.length - 1; n > 0; --i) {
for (int i = cnt.length - 1; n > 0; --i) {
++ans;
n -= counter[i];
n -= cnt[i];
}
return ans;
}
@ -89,14 +90,15 @@ class Solution {
class Solution {
public:
int halfQuestions(vector<int>& questions) {
vector<int> counter(1010);
for (int q : questions) ++counter[q];
int n = questions.size() >> 1;
sort(counter.begin(), counter.end());
int ans = 0;
for (int i = counter.size() - 1; n > 0; --i) {
int cnt[1001]{};
for (int& x : questions) {
++cnt[x];
}
sort(cnt, cnt + 1001);
int ans = 0, n = questions.size() / 2;
for (int i = 1000; n > 0; --i) {
++ans;
n -= counter[i];
n -= cnt[i];
}
return ans;
}
@ -106,19 +108,18 @@ public:
### **Go**
```go
func halfQuestions(questions []int) int {
counter := make([]int, 1010)
for _, q := range questions {
counter[q]++
func halfQuestions(questions []int) (ans int) {
cnt := make([]int, 1010)
for _, x := range questions {
cnt[x]++
}
n := len(questions) >> 1
sort.Ints(counter)
ans := 0
for i := len(counter) - 1; n > 0; i-- {
sort.Ints(cnt)
for i := len(cnt) - 1; n > 0; i-- {
ans++
n -= counter[i]
n -= cnt[i]
}
return ans
return
}
```
@ -130,21 +131,40 @@ func halfQuestions(questions []int) int {
* @return {number}
*/
var halfQuestions = function (questions) {
let counter = new Array(1010).fill(0);
for (const q of questions) {
++counter[q];
const cnt = new Array(1010).fill(0);
for (const x of questions) {
++cnt[x];
}
counter.sort((a, b) => b - a);
cnt.sort((a, b) => b - a);
let ans = 0;
let n = questions.length >> 1;
for (let i = 0; n > 0; ++i) {
++ans;
n -= counter[i];
n -= cnt[i];
}
return ans;
};
```
### **TypeScript**
```ts
function halfQuestions(questions: number[]): number {
const cnt = new Array(1010).fill(0);
for (const x of questions) {
++cnt[x];
}
cnt.sort((a, b) => b - a);
let ans = 0;
let n = questions.length >> 1;
for (let i = 0; n > 0; ++i) {
++ans;
n -= cnt[i];
}
return ans;
}
```
### **...**
```

View File

@ -1,14 +1,15 @@
class Solution {
public:
int halfQuestions(vector<int>& questions) {
vector<int> counter(1010);
for (int q : questions) ++counter[q];
int n = questions.size() >> 1;
sort(counter.begin(), counter.end());
int ans = 0;
for (int i = counter.size() - 1; n > 0; --i) {
int cnt[1001]{};
for (int& x : questions) {
++cnt[x];
}
sort(cnt, cnt + 1001);
int ans = 0, n = questions.size() / 2;
for (int i = 1000; n > 0; --i) {
++ans;
n -= counter[i];
n -= cnt[i];
}
return ans;
}

View File

@ -1,14 +1,13 @@
func halfQuestions(questions []int) int {
counter := make([]int, 1010)
for _, q := range questions {
counter[q]++
func halfQuestions(questions []int) (ans int) {
cnt := make([]int, 1010)
for _, x := range questions {
cnt[x]++
}
n := len(questions) >> 1
sort.Ints(counter)
ans := 0
for i := len(counter) - 1; n > 0; i-- {
sort.Ints(cnt)
for i := len(cnt) - 1; n > 0; i-- {
ans++
n -= counter[i]
n -= cnt[i]
}
return ans
return
}

View File

@ -1,15 +1,15 @@
class Solution {
public int halfQuestions(int[] questions) {
int[] counter = new int[1010];
for (int q : questions) {
++counter[q];
int[] cnt = new int[1010];
for (int x : questions) {
++cnt[x];
}
Arrays.sort(counter);
Arrays.sort(cnt);
int ans = 0;
int n = questions.length >> 1;
for (int i = counter.length - 1; n > 0; --i) {
for (int i = cnt.length - 1; n > 0; --i) {
++ans;
n -= counter[i];
n -= cnt[i];
}
return ans;
}

View File

@ -3,16 +3,16 @@
* @return {number}
*/
var halfQuestions = function (questions) {
let counter = new Array(1010).fill(0);
for (const q of questions) {
++counter[q];
const cnt = new Array(1010).fill(0);
for (const x of questions) {
++cnt[x];
}
counter.sort((a, b) => b - a);
cnt.sort((a, b) => b - a);
let ans = 0;
let n = questions.length >> 1;
for (let i = 0; n > 0; ++i) {
++ans;
n -= counter[i];
n -= cnt[i];
}
return ans;
};

View File

@ -1,11 +1,10 @@
class Solution:
def halfQuestions(self, questions: List[int]) -> int:
counter = Counter(questions)
n = len(questions) >> 1
ans = 0
for i, v in counter.most_common():
cnt = Counter(questions)
ans, n = 0, len(questions) >> 1
for _, v in cnt.most_common():
ans += 1
if v >= n:
return ans
n -= v
if n <= 0:
break
return ans

View File

@ -0,0 +1,14 @@
function halfQuestions(questions: number[]): number {
const cnt = new Array(1010).fill(0);
for (const x of questions) {
++cnt[x];
}
cnt.sort((a, b) => b - a);
let ans = 0;
let n = questions.length >> 1;
for (let i = 0; n > 0; ++i) {
++ans;
n -= cnt[i];
}
return ans;
}

View File

@ -60,15 +60,15 @@ int gray(x) {
}
```
我们可以直接将 $[0,..2^n - 1]$ 这些整数映射成对应的格雷码数组,然后找到 $start$ 在格雷码数组中的位置,将格雷码数组从该位置开始截取,再将截取的部分拼接到格雷码数组的前面,就得到了题目要求的排列。
我们可以直接将 $[0,..2^n - 1]$ 这些整数转换成对应的格雷码数组,然后找到 $start$ 在格雷码数组中的位置,将格雷码数组从该位置开始截取,再将截取的部分拼接到格雷码数组的前面,就得到了题目要求的排列。
时间复杂度 $O(2^n)$,其中 $n$ 为题目给定的整数。忽略答案的空间消耗,空间复杂度 $O(1)$。
时间复杂度 $O(2^n)$空间复杂度 $O(2^n)$。其中 $n$ 为题目给定的整数。
**方法二:转换优化**
由于 $gray(0) = 0$,那么 $gray(0) \oplus start = start$,而 $gray(i)$ 与 $gray(i-1)$ 只有一个二进制位不同,所以 $gray(i) \oplus start$ 与 $gray(i-1) \oplus start$ 也只有一个二进制位不同。
因此,我们也可以直接将 $[0,..2^n - 1]$ 这些整数映射成对应的 $gray(i) \oplus start$,即可得到首项为 $start$ 的格雷码排列。
因此,我们也可以直接将 $[0,..2^n - 1]$ 这些整数转换成对应的 $gray(i) \oplus start$,即可得到首项为 $start$ 的格雷码排列。
时间复杂度 $O(2^n)$,其中 $n$ 为题目给定的整数。忽略答案的空间消耗,空间复杂度 $O(1)$。