正式切换到力扣刷题记录

This commit is contained in:
huangge1199@hotmail.com 2021-04-29 23:21:52 +08:00
parent 2efb14912d
commit a1bdf655f1
382 changed files with 9 additions and 4891 deletions

7
.gitignore vendored
View File

@ -1,5 +1,4 @@
/.idea/
/**/*.iml
/**/src/test/
/LeetCode/target/
/LeetCode/src/main/java/leetcode/editor/cn/doc/
/leet-code.iml
/src/test/
/src/main/java/leetcode/editor/cn/doc/

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>Code</artifactId>
<groupId>com.code</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>CodeWar</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
</project>

View File

@ -1,18 +0,0 @@
package com.code.war.entry;
/**
* @Author: hyy
* @Date: 2020-04-24 15:53
*/
public class Token {
private String text;
private String type;
public Token(String text, String type) {
this.text = text;
this.type = type;
System.out.println("text=" + text + ",type=" + type);
}
}

View File

@ -1,56 +0,0 @@
package com.code.war.study.t20200213;
import java.util.ArrayList;
import java.util.List;
/**
* 4 kyu
* Sum of Intervals
*
* @Author: hyy
* @Date: 2020-02-13 22:07
*/
public class Interval {
public static int sumIntervals(int[][] intervals) {
if (intervals == null || intervals.length == 0) {
return 0;
}
List<List<Integer>> list = new ArrayList<>();
for (int i = 0; i < intervals.length; i++) {
int start = intervals[i][0];
int end = intervals[i][1];
if (list.size() > 0) {
for (int j = list.size() - 1; j >= 0; j--) {
List<Integer> temp = list.get(j);
if (start >= temp.get(0) && end <= temp.get(1)) {
list.remove(j);
start = temp.get(0);
end = temp.get(1);
break;
} else if (start >= temp.get(0) && start <= temp.get(1) && end >= temp.get(1)) {
start = temp.get(0);
list.remove(j);
j = list.size();
} else if (start <= temp.get(0) && end <= temp.get(1) && end >= temp.get(0)) {
end = temp.get(1);
list.remove(j);
j = list.size();
} else if (start <= temp.get(0) && end >= temp.get(1)) {
list.remove(j);
}
}
}
List<Integer> temp = new ArrayList<>();
temp.add(start);
temp.add(end);
list.add(temp);
}
int sum = 0;
for (List<Integer> temp : list) {
sum += temp.get(1) - temp.get(0);
}
return sum;
}
}

View File

@ -1,68 +0,0 @@
package com.code.war.study.t20200214;
/**
* @Author: hyy
* @Date: 2020-02-14 09:32
*/
public class Runes {
public static int solveExpression(final String expression) {
int missingDigit = -1;
String[] nums = new String[]{"", "", ""};
String op = "";
int j = 0;
nums = new String[]{expression.substring(0, 1), "", ""};
for (int i = 1; i < expression.length(); i++) {
if ("1234567890?".contains(expression.substring(i, i + 1))) {
nums[j] += expression.substring(i, i + 1);
} else if ("+*".contains(expression.substring(i, i + 1))) {
op = expression.substring(i, i + 1);
j++;
} else if ("-".equals(expression.substring(i, i + 1))) {
if ("+-*=".contains(expression.substring(i - 1, i))) {
nums[j] += expression.substring(i, i + 1);
} else {
op = "-";
j++;
}
} else {
j++;
}
}
for (int num = 0; num < 10; num++) {
String temp = expression;
temp = temp.replaceAll("\\?", String.valueOf(num));
if(num==0&&(nums[0].indexOf("?")==0||nums[1].indexOf("?")==0||nums[2].indexOf("?")==0)){
continue;
}
int num1 = Integer.parseInt(nums[0].replaceAll("\\?", String.valueOf(num)));
int num2 = Integer.parseInt(nums[1].replaceAll("\\?", String.valueOf(num)));
int num3 = Integer.parseInt(nums[2].replaceAll("\\?", String.valueOf(num)));
int result = 0;
switch (op) {
case "+":
result = num1 + num2;
break;
case "-":
result = num1 - num2;
break;
case "*":
result = num1 * num2;
break;
default:
break;
}
if (result == num3) {
missingDigit = num;
break;
}
}
//Write code to determine the missing digit or unknown rune
//Expression will always be in the form
//(number)[opperator](number)=(number)
//Unknown digit will not be the same as any other digits used in expression
return missingDigit;
}
}

View File

@ -1,63 +0,0 @@
package com.code.war.study.t20200215;
import java.util.Arrays;
import java.util.List;
/**
* @Author: hyy
* @Date: 2020-02-15 17:33
*/
public class CaesarCipher {
public static List<String> movingShift(String s, int shift) {
int length = s.length() % 5 == 0 ? s.length() / 5 : s.length() / 5 + 1;
int count = 0;
List<String> result = Arrays.asList("", "", "", "", "");
for (int i = 0; i < s.length(); i++) {
int index = index = (int) s.charAt(i) + shift + i;
char ch = ' ';
if ((int) s.charAt(i) > 64 && (int) s.charAt(i) < 91) {
while (index > 90) {
index -= 26;
}
ch = (char) (index);
} else if ((int) s.charAt(i) > 96 && (int) s.charAt(i) < 123) {
while (index > 122) {
index -= 26;
}
ch = (char) (index);
} else {
ch = s.charAt(i);
}
result.set(i / length, result.get(i / length) + ch);
}
return result;
}
public static String demovingShift(List<String> s, int shift) {
String result = "";
int num = 0;
for (String str : s) {
for (int i = 0; i < str.length(); i++) {
int index = index = (int) str.charAt(i) - shift - num;
char ch = ' ';
if ((int) str.charAt(i) > 64 && (int) str.charAt(i) < 91) {
while (index < 65) {
index += 26;
}
ch = (char) (index);
} else if ((int) str.charAt(i) > 96 && (int) str.charAt(i) < 123) {
while (index < 97) {
index += 26;
}
ch = (char) (index);
} else {
ch = str.charAt(i);
}
result += ch;
num++;
}
}
return result;
}
}

View File

@ -1,48 +0,0 @@
package com.code.war.study.t20200217;
/**
* @Author: hyy
* @Date: 2020-02-17 20:40
*/
public class Emirps {
public static long[] findEmirp(long n) {
// your code
long[] emirps = new long[(int) n];
long[] temp = new long[(int) n];
int eIndex = 0;
int rIndex = 0;
int sum = 0;
for (long i = 2; i < n; i++) {
boolean isEmirps = true;
for (int j = 0; j < eIndex; j++) {
if (i % emirps[j] == 0) {
isEmirps = false;
break;
}
}
if (isEmirps) {
emirps[eIndex] = i;
eIndex++;
String str = String.valueOf(i);
int count = 0;
int start = 0;
int end = str.length() - 1;
while (start < end) {
if (str.charAt(start) == str.charAt(end)) {
count++;
}
start++;
end++;
}
if (count < str.length() / 2) {
temp[rIndex] = i;
rIndex++;
sum += i;
}
}
}
return new long[]{rIndex, rIndex > 0 ? temp[rIndex - 1] : 0, sum};
}
}

View File

@ -1,26 +0,0 @@
package com.code.war.study.t20200217;
/**
* Scramblies
*
* @Author: hyy
* @Date: 2020-02-17 09:55
*/
public class Scramblies {
public static boolean scramble(String str1, String str2) {
// your code
boolean result = true;
for (int i=0;i<str2.length();i++){
int index = str1.indexOf(str2.substring(i,i+1));
if(index>=0){
str1 = str1.substring(0,index)+str1.substring(index+1);
}else{
result=false;
break;
}
}
return result;
}
}

View File

@ -1,36 +0,0 @@
package com.code.war.study.t20200624;
import java.util.ArrayList;
import java.util.List;
/**
* @Author: hyy
* @Date: 2020-06-24 15:10
*/
public class Hamming {
public static long hamming(int n) {
List<Long> result = new ArrayList<>();
int num2 = 0;
int num3 = 0;
int num5 = 0;
int count = 1;
result.add(1L);
while (n > count) {
long temp = Math.min(Math.min(result.get(num2) * 2, result.get(num3) * 3), result.get(num5) * 5);
if (temp == result.get(num2) * 2) {
num2++;
}
if (temp == result.get(num3) * 3) {
num3++;
}
if (temp == result.get(num5) * 5) {
num5++;
}
count++;
result.add(temp);
}
return result.get(result.size() - 1);
}
}

View File

@ -1,43 +0,0 @@
package com.code.war.study.t20200624;
import java.util.*;
/**
* @Author: hyy
* @Date: 2020-06-24 14:16
*/
public class ObservedPin {
public static List<String> getPINs(String observed) {
Map<String,List<String>> map = new HashMap<>(10);
map.put("1", Arrays.asList("1","2","4"));
map.put("2",Arrays.asList("1","5","2","3"));
map.put("3", Arrays.asList("5","6","3"));
map.put("4",Arrays.asList("1","5","7","4"));
map.put("5",Arrays.asList("2","4","6","8","5"));
map.put("6",Arrays.asList("3","5","9","6"));
map.put("7", Arrays.asList("4","8", "7"));
map.put("8",Arrays.asList("5", "7", "8", "9", "0"));
map.put("9",Arrays.asList("6","8","9"));
map.put("0", Arrays.asList("0","8"));
List<String> result = new ArrayList<>();
for (int i = 0; i < observed.length(); i++) {
List<String> pin = map.get(observed.substring(i,i+1));
if(result.size()==0){
for (int j = 0; j < pin.size(); j++) {
result.add(pin.get(j));
}
}else{
List<String> temp = new ArrayList<>();
for (int j = 0; j < pin.size(); j++) {
for (int k = 0; k < result.size(); k++) {
temp.add(result.get(k)+pin.get(j));
}
}
result = temp;
}
}
return result;
}
}

201
LICENSE
View File

@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -1,2 +0,0 @@
# 链表 LinkNode

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>Code</artifactId>
<groupId>com.code</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>LeetCode</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
</project>

View File

@ -1,74 +0,0 @@
思路:
先找好遍历顺序, top和bottom分别为行的上下界, 然后对列进行遍历, 利用前缀和+二分查找的方式更新ans
![](https://pic.leetcode-cn.com/1619058643-fkFedw-image.png)
### 1 | 二分查找+一维前缀和
这种方式在行遍历时先用一个sum[]保存每一列的和, 然后在列遍历的过程中动态维护前缀和
```cpp
class Solution {
public:
int maxSumSubmatrix(vector<vector<int>>& matrix, int k) {
int m = matrix.size(), n = matrix[0].size(), ans = INT_MIN;
// top
for (int i = 0; i < m; ++i) {
// bottom
vector<int> sum(n, 0);
for (int j = i; j < m; ++j) {
set<int> st{0};
int r = 0;
for (int z = 0; z < n; ++z) {
sum[z] += matrix[j][z];
r += sum[z];
auto lb = st.lower_bound(r - k);
if (lb != st.end()) {
ans = max(ans, r - *lb);
}
st.insert(r);
}
}
}
return ans;
}
};
```
### 2 | 二分查找+二维前缀和(积分图)
先对矩阵进行预处理, 可以减少动态维护前缀和时候重复计算的开销, 但是增大了空间复杂度
```cpp
class Solution {
public:
int maxSumSubmatrix(vector<vector<int>>& matrix, int k) {
int m = matrix.size(), n = matrix[0].size(), ans = INT_MIN;
vector<vector<int>> pre(m + 1, vector<int>(n + 1, 0));
// 积分图
for (int i = 1; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
pre[i][j] = pre[i - 1][j] + pre[i][j - 1] - pre[i - 1][j - 1] + matrix[i - 1][j - 1];
}
}
// top
for (int i = 1; i <= m; ++i) {
// bottom
for (int j = i; j <= m; ++j) {
set<int> st{0};
for (int z = 1; z <= n; ++z) {
int r = pre[j][z] - pre[i - 1][z];
auto lb = st.lower_bound(r - k);
if (lb != st.end()) {
ans = max(ans, r - *lb);
}
st.insert(r);
}
}
}
return ans;
}
};
```

View File

@ -1,82 +0,0 @@
### 解数独思路:
类似人的思考方式去尝试,`行``列`,还有 `3*3` 的方格内数字是 1~9 不能重复。
我们尝试填充,如果发现重复了,那么擦除重新进行新一轮的尝试,直到把整个数组填充完成。
### 算法步骤:
- 数独首先`行``列`,还有 `3*3` 的方格内数字是 1~9 不能重复。
- 声明布尔数组,表明行列中某个数字是否被使用了, 被用过视为 `true`,没用过为 `false`
- 初始化布尔数组,表明哪些数字已经被使用过了。
- 尝试去填充数组,只要`行``列` 还有 `3*3` 的方格内 出现已经被使用过的数字,我们就不填充,否则尝试填充。
- 如果填充失败,那么我们需要回溯。将原来尝试填充的地方改回来。
- 递归直到数独被填充完成。
### 代码:
代码看着多, 其实逻辑非常清楚,很容易理解。
```java [-Java]
class Solution {
public void solveSudoku(char[][] board) {
// 三个布尔数组 表明 行, 列, 还有 3*3 的方格的数字是否被使用过
boolean[][] rowUsed = new boolean[9][10];
boolean[][] colUsed = new boolean[9][10];
boolean[][][] boxUsed = new boolean[3][3][10];
// 初始化
for(int row = 0; row < board.length; row++){
for(int col = 0; col < board[0].length; col++) {
int num = board[row][col] - '0';
if(1 <= num && num <= 9){
rowUsed[row][num] = true;
colUsed[col][num] = true;
boxUsed[row/3][col/3][num] = true;
}
}
}
// 递归尝试填充数组
recusiveSolveSudoku(board, rowUsed, colUsed, boxUsed, 0, 0);
}
private boolean recusiveSolveSudoku(char[][]board, boolean[][]rowUsed, boolean[][]colUsed, boolean[][][]boxUsed, int row, int col){
// 边界校验, 如果已经填充完成, 返回true, 表示一切结束
if(col == board[0].length){
col = 0;
row++;
if(row == board.length){
return true;
}
}
// 是空则尝试填充, 否则跳过继续尝试填充下一个位置
if(board[row][col] == '.') {
// 尝试填充1~9
for(int num = 1; num <= 9; num++){
boolean canUsed = !(rowUsed[row][num] || colUsed[col][num] || boxUsed[row/3][col/3][num]);
if(canUsed){
rowUsed[row][num] = true;
colUsed[col][num] = true;
boxUsed[row/3][col/3][num] = true;
board[row][col] = (char)('0' + num);
if(recusiveSolveSudoku(board, rowUsed, colUsed, boxUsed, row, col + 1)){
return true;
}
board[row][col] = '.';
rowUsed[row][num] = false;
colUsed[col][num] = false;
boxUsed[row/3][col/3][num] = false;
}
}
} else {
return recusiveSolveSudoku(board, rowUsed, colUsed, boxUsed, row, col + 1);
}
return false;
}
}
```

View File

@ -1,263 +0,0 @@
#### 方法一:动态规划
**思路与算法**
对于给定的字符串 *s*,设它的长度为 *n*,其中的字符从左到右依次为 ![s\[1\],s\[2\],\cdots,s\[n\] ](./p__s_1_,_s_2_,_cdots,_s_n__.png) 。我们可以使用动态规划的方法计算出字符串 *s* 的解码方法数。
具体地,设 *f_i* 表示字符串 *s* 的前 *i* 个字符 *s[1..i]* 的解码方法数。在进行状态转移时,我们可以考虑最后一次解码使用了 *s* 中的哪些字符,那么会有下面的两种情况:
- 第一种情况是我们使用了一个字符,即 *s[i]* 进行解码,那么只要 ![s\[i\]\neq0 ](./p__s_i__neq_0_.png) ,它就可以被解码成 ![\text{A}\sim\text{I} ](./p__text{A}_sim_text{I}_.png) 中的某个字母。由于剩余的前 *i-1* 个字符的解码方法数为 *f_{i-1}*,因此我们可以写出状态转移方程:
![f_i=f_{i-1},\quad其中~s\[i\]\neq0 ](./p_______f_i_=_f_{i-1},_quad_其中_~_s_i__neq_0______.png)
- 第二种情况是我们使用了两个字符,即 *s[i-1]**s[i]* 进行编码。与第一种情况类似,*s[i-1]* 不能等于 *0*,并且 *s[i-1]**s[i]* 组成的整数必须小于等于 *26*,这样它们就可以被解码成 ![\text{J}\sim\text{Z} ](./p__text{J}_sim_text{Z}_.png) 中的某个字母。由于剩余的前 *i-2* 个字符的解码方法数为 *f_{i-2}*,因此我们可以写出状态转移方程:
![f_i=f_{i-2},\quad其中~s\[i-1\]\neq0~并且~10\cdots\[i-1\]+s\[i\]\leq26 ](./p_______f_i_=_f_{i-2},_quad_其中_~_s_i-1__neq_0_~并且~_10cdot_s_i-1_+s_i__leq_26______.png)
需要注意的是,只有当 *i>1* 时才能进行转移,否则 *s[i-1]* 不存在。
将上面的两种状态转移方程在对应的条件满足时进行累加,即可得到 *f_i* 的值。在动态规划完成后,最终的答案即为 *f_n*
**细节**
动态规划的边界条件为:
*
f_0 = 1
*
即**空字符串可以有 *1* 种解码方法,解码出一个空字符串**。
同时,由于在大部分语言中,字符串的下标是从 *0* 而不是 *1* 开始的,因此在代码的编写过程中,我们需要将所有字符串的下标减去 *1*,与使用的语言保持一致。
**代码**
```C++ [sol11-C++]
class Solution {
public:
int numDecodings(string s) {
int n = s.size();
vector<int> f(n + 1);
f[0] = 1;
for (int i = 1; i <= n; ++i) {
if (s[i - 1] != '0') {
f[i] += f[i - 1];
}
if (i > 1 && s[i - 2] != '0' && ((s[i - 2] - '0') * 10 + (s[i - 1] - '0') <= 26)) {
f[i] += f[i - 2];
}
}
return f[n];
}
};
```
```Java [sol11-Java]
class Solution {
public int numDecodings(String s) {
int n = s.length();
int[] f = new int[n + 1];
f[0] = 1;
for (int i = 1; i <= n; ++i) {
if (s.charAt(i - 1) != '0') {
f[i] += f[i - 1];
}
if (i > 1 && s.charAt(i - 2) != '0' && ((s.charAt(i - 2) - '0') * 10 + (s.charAt(i - 1) - '0') <= 26)) {
f[i] += f[i - 2];
}
}
return f[n];
}
}
```
```Python [sol11-Python3]
class Solution:
def numDecodings(self, s: str) -> int:
n = len(s)
f = [1] + [0] * n
for i in range(1, n + 1):
if s[i - 1] != '0':
f[i] += f[i - 1]
if i > 1 and s[i - 2] != '0' and int(s[i-2:i]) <= 26:
f[i] += f[i - 2]
return f[n]
```
```JavaScript [sol11-JavaScript]
var numDecodings = function(s) {
const n = s.length;
const f = new Array(n + 1).fill(0);
f[0] = 1;
for (let i = 1; i <= n; ++i) {
if (s[i - 1] !== '0') {
f[i] += f[i - 1];
}
if (i > 1 && s[i - 2] != '0' && ((s[i - 2] - '0') * 10 + (s[i - 1] - '0') <= 26)) {
f[i] += f[i - 2];
}
}
return f[n];
};
```
```go [sol11-Golang]
func numDecodings(s string) int {
n := len(s)
f := make([]int, n+1)
f[0] = 1
for i := 1; i <= n; i++ {
if s[i-1] != '0' {
f[i] += f[i-1]
}
if i > 1 && s[i-2] != '0' && ((s[i-2]-'0')*10+(s[i-1]-'0') <= 26) {
f[i] += f[i-2]
}
}
return f[n]
}
```
```C [sol11-C]
int numDecodings(char* s) {
int n = strlen(s);
int f[n + 1];
memset(f, 0, sizeof(f));
f[0] = 1;
for (int i = 1; i <= n; ++i) {
if (s[i - 1] != '0') {
f[i] += f[i - 1];
}
if (i > 1 && s[i - 2] != '0' && ((s[i - 2] - '0') * 10 + (s[i - 1] - '0') <= 26)) {
f[i] += f[i - 2];
}
}
return f[n];
}
```
注意到在状态转移方程中,*f_i* 的值仅与 *f_{i-1}**f_{i-2}* 有关,因此我们可以使用三个变量进行状态转移,省去数组的空间。
```C++ [sol12-C++]
class Solution {
public:
int numDecodings(string s) {
int n = s.size();
// a = f[i-2], b = f[i-1], c = f[i]
int a = 0, b = 1, c;
for (int i = 1; i <= n; ++i) {
c = 0;
if (s[i - 1] != '0') {
c += b;
}
if (i > 1 && s[i - 2] != '0' && ((s[i - 2] - '0') * 10 + (s[i - 1] - '0') <= 26)) {
c += a;
}
tie(a, b) = {b, c};
}
return c;
}
};
```
```Java [sol12-Java]
class Solution {
public int numDecodings(String s) {
int n = s.length();
// a = f[i-2], b = f[i-1], c=f[i]
int a = 0, b = 1, c = 0;
for (int i = 1; i <= n; ++i) {
c = 0;
if (s.charAt(i - 1) != '0') {
c += b;
}
if (i > 1 && s.charAt(i - 2) != '0' && ((s.charAt(i - 2) - '0') * 10 + (s.charAt(i - 1) - '0') <= 26)) {
c += a;
}
a = b;
b = c;
}
return c;
}
}
```
```Python [sol12-Python3]
class Solution:
def numDecodings(self, s: str) -> int:
n = len(s)
# a = f[i-2], b = f[i-1], c = f[i]
a, b, c = 0, 1, 0
for i in range(1, n + 1):
c = 0
if s[i - 1] != '0':
c += b
if i > 1 and s[i - 2] != '0' and int(s[i-2:i]) <= 26:
c += a
a, b = b, c
return c
```
```JavaScript [sol12-JavaScript]
var numDecodings = function(s) {
const n = s.length;
// a = f[i-2], b = f[i-1], c = f[i]
let a = 0, b = 1, c = 0;
for (let i = 1; i <= n; ++i) {
c = 0;
if (s[i - 1] !== '0') {
c += b;
}
if (i > 1 && s[i - 2] != '0' && ((s[i - 2] - '0') * 10 + (s[i - 1] - '0') <= 26)) {
c += a;
}
a = b;
b = c;
}
return c;
};
```
```go [sol12-Golang]
func numDecodings(s string) int {
n := len(s)
// a = f[i-2], b = f[i-1], c = f[i]
a, b, c := 0, 1, 0
for i := 1; i <= n; i++ {
c = 0
if s[i-1] != '0' {
c += b
}
if i > 1 && s[i-2] != '0' && ((s[i-2]-'0')*10+(s[i-1]-'0') <= 26) {
c += a
}
a, b = b, c
}
return c
}
```
```C [sol12-C]
int numDecodings(char* s) {
int n = strlen(s);
// a = f[i-2], b = f[i-1], c = f[i]
int a = 0, b = 1, c;
for (int i = 1; i <= n; ++i) {
c = 0;
if (s[i - 1] != '0') {
c += b;
}
if (i > 1 && s[i - 2] != '0' && ((s[i - 2] - '0') * 10 + (s[i - 1] - '0') <= 26)) {
c += a;
}
a = b, b = c;
}
return c;
}
```
**复杂度分析**
- 时间复杂度:*O(n)*,其中 *n* 是字符串 *s* 的长度。
- 空间复杂度:*O(n)* 或 *O(1)*。如果使用数组进行状态转移,空间复杂度为 *O(n)*;如果仅使用三个变量,空间复杂度为 *O(1)*

View File

@ -1,914 +0,0 @@
#### 前言
我们可以考虑按照「行优先」的顺序依次枚举每一个空白格中填的数字,通过递归 + 回溯的方法枚举所有可能的填法。当递归到最后一个空白格后,如果仍然没有冲突,说明我们找到了答案;在递归的过程中,如果当前的空白格不能填下任何一个数字,那么就进行回溯。
由于每个数字在同一行、同一列、同一个九宫格中只会出现一次,因此我们可以使用 ![\textit{line}\[i\] ](./p__textit{line}_i__.png) ![\textit{column}\[j\] ](./p__textit{column}_j__.png) ![\textit{block}\[x\]\[y\] ](./p__textit{block}_x__y__.png) 分别表示第 *i* 行,第 *j* 列,第 *(x, y)* 个九宫格中填写数字的情况。在下面给出的三种方法中,我们将会介绍两种不同的表示填写数字情况的方法。
> 九宫格的范围为 ![0\leqx\leq2 ](./p__0_leq_x_leq_2_.png) 以及 ![0\leqy\leq2 ](./p__0_leq_y_leq_2_.png) 。
> 具体地,第 *i* 行第 *j* 列的格子位于第 ![(\lfloori/3\rfloor,\lfloorj/3\rfloor) ](./p___lfloor_i_3_rfloor,_lfloor_j_3_rfloor__.png) 个九宫格中,其中 ![\lflooru\rfloor ](./p__lfloor_u_rfloor_.png) 表示对 *u* 向下取整。
由于这些方法均以递归 + 回溯为基础,算法运行的时间(以及时间复杂度)很大程度取决于给定的输入数据,而我们很难找到一个非常精确的渐进紧界。因此这里只给出一个较为宽松的渐进复杂度上界 ![O(9^{9\times9}) ](./p__O_9^{9_times_9}__.png) ,即最多有 ![9\times9 ](./p__9_times_9_.png) 个空白格,每个格子可以填 *[1, 9]* 中的任意整数。
#### 方法一:递归
**思路**
最容易想到的方法是用一个数组记录每个数字是否出现。由于我们可以填写的数字范围为 *[1, 9]*,而数组的下标从 *0* 开始,因此在存储时,我们使用一个长度为 *9* 的布尔类型的数组,其中 *i* 个元素的值为 ![\text{True} ](./p__text{True}_.png) ,当且仅当数字 *i+1* 出现过。例如我们用 ![\textit{line}\[2\]\[3\]=\text{True} ](./p__textit{line}_2__3__=_text{True}_.png) 表示数字 *4* 在第 *2* 行已经出现过,那么当我们在遍历到第 *2* 行的空白格时,就不能填入数字 *4*
**算法**
我们首先对整个数独数组进行遍历,当我们遍历到第 *i* 行第 *j* 列的位置:
- 如果该位置是一个空白格,那么我们将其加入一个用来存储空白格位置的列表中,方便后续的递归操作;
- 如果该位置是一个数字 *x*,那么我们需要将 ![\textit{line}\[i\]\[x-1\] ](./p__textit{line}_i__x-1__.png) ![\textit{column}\[j\]\[x-1\] ](./p__textit{column}_j__x-1__.png) 以及 ![\textit{block}\[\lfloori/3\rfloor\]\[\lfloorj/3\rfloor\]\[x-1\] ](./p__textit{block}_lfloor_i_3_rfloor__lfloor_j_3_rfloor__x-1__.png) 均置为 ![\text{True} ](./p__text{True}_.png) 。
当我们结束了遍历过程之后,就可以开始递归枚举。当递归到第 *i* 行第 *j* 列的位置时,我们枚举填入的数字 *x*。根据题目的要求,数字 *x* 不能和当前行、列、九宫格中已经填入的数字相同,因此 ![\textit{line}\[i\]\[x-1\] ](./p__textit{line}_i__x-1__.png) ![\textit{column}\[j\]\[x-1\] ](./p__textit{column}_j__x-1__.png) 以及 ![\textit{block}\[\lfloori/3\rfloor\]\[\lfloorj/3\rfloor\]\[x-1\] ](./p__textit{block}_lfloor_i_3_rfloor__lfloor_j_3_rfloor__x-1__.png) 必须均为 ![\text{False} ](./p__text{False}_.png) 。
当我们填入了数字 *x* 之后,我们要将上述的三个值都置为 ![\text{True} ](./p__text{True}_.png) ,并且继续对下一个空白格位置进行递归。在回溯到当前递归层时,我们还要将上述的三个值重新置为 ![\text{False} ](./p__text{False}_.png) 。
**代码**
```C++ [sol1-C++]
class Solution {
private:
bool line[9][9];
bool column[9][9];
bool block[3][3][9];
bool valid;
vector<pair<int, int>> spaces;
public:
void dfs(vector<vector<char>>& board, int pos) {
if (pos == spaces.size()) {
valid = true;
return;
}
auto [i, j] = spaces[pos];
for (int digit = 0; digit < 9 && !valid; ++digit) {
if (!line[i][digit] && !column[j][digit] && !block[i / 3][j / 3][digit]) {
line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;
board[i][j] = digit + '0' + 1;
dfs(board, pos + 1);
line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = false;
}
}
}
void solveSudoku(vector<vector<char>>& board) {
memset(line, false, sizeof(line));
memset(column, false, sizeof(column));
memset(block, false, sizeof(block));
valid = false;
for (int i = 0; i < 9; ++i) {
for (int j = 0; j < 9; ++j) {
if (board[i][j] == '.') {
spaces.emplace_back(i, j);
}
else {
int digit = board[i][j] - '0' - 1;
line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;
}
}
}
dfs(board, 0);
}
};
```
```Java [sol1-Java]
class Solution {
private boolean[][] line = new boolean[9][9];
private boolean[][] column = new boolean[9][9];
private boolean[][][] block = new boolean[3][3][9];
private boolean valid = false;
private List<int[]> spaces = new ArrayList<int[]>();
public void solveSudoku(char[][] board) {
for (int i = 0; i < 9; ++i) {
for (int j = 0; j < 9; ++j) {
if (board[i][j] == '.') {
spaces.add(new int[]{i, j});
} else {
int digit = board[i][j] - '0' - 1;
line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;
}
}
}
dfs(board, 0);
}
public void dfs(char[][] board, int pos) {
if (pos == spaces.size()) {
valid = true;
return;
}
int[] space = spaces.get(pos);
int i = space[0], j = space[1];
for (int digit = 0; digit < 9 && !valid; ++digit) {
if (!line[i][digit] && !column[j][digit] && !block[i / 3][j / 3][digit]) {
line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;
board[i][j] = (char) (digit + '0' + 1);
dfs(board, pos + 1);
line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = false;
}
}
}
}
```
```Python [sol1-Python3]
class Solution:
def solveSudoku(self, board: List[List[str]]) -> None:
def dfs(pos: int):
nonlocal valid
if pos == len(spaces):
valid = True
return
i, j = spaces[pos]
for digit in range(9):
if line[i][digit] == column[j][digit] == block[i // 3][j // 3][digit] == False:
line[i][digit] = column[j][digit] = block[i // 3][j // 3][digit] = True
board[i][j] = str(digit + 1)
dfs(pos + 1)
line[i][digit] = column[j][digit] = block[i // 3][j // 3][digit] = False
if valid:
return
line = [[False] * 9 for _ in range(9)]
column = [[False] * 9 for _ in range(9)]
block = [[[False] * 9 for _a in range(3)] for _b in range(3)]
valid = False
spaces = list()
for i in range(9):
for j in range(9):
if board[i][j] == ".":
spaces.append((i, j))
else:
digit = int(board[i][j]) - 1
line[i][digit] = column[j][digit] = block[i // 3][j // 3][digit] = True
dfs(0)
```
```Golang [sol1-Golang]
func solveSudoku(board [][]byte) {
var line, column [9][9]bool
var block [3][3][9]bool
var spaces [][2]int
for i, row := range board {
for j, b := range row {
if b == '.' {
spaces = append(spaces, [2]int{i, j})
} else {
digit := b - '1'
line[i][digit] = true
column[j][digit] = true
block[i/3][j/3][digit] = true
}
}
}
var dfs func(int) bool
dfs = func(pos int) bool {
if pos == len(spaces) {
return true
}
i, j := spaces[pos][0], spaces[pos][1]
for digit := byte(0); digit < 9; digit++ {
if !line[i][digit] && !column[j][digit] && !block[i/3][j/3][digit] {
line[i][digit] = true
column[j][digit] = true
block[i/3][j/3][digit] = true
board[i][j] = digit + '1'
if dfs(pos + 1) {
return true
}
line[i][digit] = false
column[j][digit] = false
block[i/3][j/3][digit] = false
}
}
return false
}
dfs(0)
}
```
```C [sol1-C]
bool line[9][9];
bool column[9][9];
bool block[3][3][9];
bool valid;
int* spaces[81];
int spacesSize;
void dfs(char** board, int pos) {
if (pos == spacesSize) {
valid = true;
return;
}
int i = spaces[pos][0], j = spaces[pos][1];
for (int digit = 0; digit < 9 && !valid; ++digit) {
if (!line[i][digit] && !column[j][digit] && !block[i / 3][j / 3][digit]) {
line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;
board[i][j] = digit + '0' + 1;
dfs(board, pos + 1);
line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = false;
}
}
}
void solveSudoku(char** board, int boardSize, int* boardColSize) {
memset(line, false, sizeof(line));
memset(column, false, sizeof(column));
memset(block, false, sizeof(block));
valid = false;
spacesSize = 0;
for (int i = 0; i < 9; ++i) {
for (int j = 0; j < 9; ++j) {
if (board[i][j] == '.') {
spaces[spacesSize] = malloc(sizeof(int) * 2);
spaces[spacesSize][0] = i;
spaces[spacesSize++][1] = j;
} else {
int digit = board[i][j] - '0' - 1;
line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;
}
}
}
dfs(board, 0);
}
```
#### 方法二:位运算优化
**思路与算法**
在方法一中,我们使用了长度为 *9* 的数组表示每个数字是否出现过。我们同样也可以借助位运算,仅使用一个整数表示每个数字是否出现过。
具体地,数 *b* 的二进制表示的第 *i* 位(从低到高,最低位为第 *0* 位)为 *1*,当且仅当数字 *i+1* 已经出现过。例如当 *b* 的二进制表示为 *(011000100)_2* 时,就表示数字 *3**7**8* 已经出现过。
位运算有一些基础的使用技巧。下面列举了所有在代码中使用到的技巧:
- 对于第 *i* 行第 *j* 列的位置,![\textit{line}\[i\]~|~\textit{column}\[j\]~|~\textit{block}\[\lfloori/3\rfloor\]\[\lfloorj/3\rfloor\] ](./p__textit{line}_i__~|~_textit{column}_j__~|~_textit{block}_lfloor_i_3_rfloor__lfloor_j_3_rfloor__.png) 中第 *k* 位为 *1*,表示该位置不能填入数字 *k+1*(因为已经出现过),其中 *|* 表示按位或运算。如果我们对这个值进行 ![\sim ](./p__sim_.png) 按位取反运算,那么第 *k* 位为 *1* 就表示该位置可以填入数字 *k+1*,我们就可以通过寻找 *1* 来进行枚举。由于在进行按位取反运算后,这个数的高位也全部变成了 *1*,而这是我们不应当枚举到的,因此我们需要将这个数和 ![(111111111)_2=(\text{1FF})_{16} ](./p___111111111__2_=__text{1FF}__{16}_.png) 进行按位与运算 ![\& ](./p__&_.png) ,将所有无关的位置为 *0*
- 我们可以使用按位异或运算 ![\wedge ](./p__wedge_.png) ,将第 *i* 位从 *0* 变为 *1*,或从 *1* 变为 *0*。具体地,与数 *1 << i* 进行按位异或运算即可,其中 *<<* 表示左移运算;
- 我们可以用 ![b~\&~(-b) ](./p__b_~&~__-b__.png) 得到 *b* 二进制表示中最低位的 *1*,这是因为 *(-b)* 在计算机中以补码的形式存储,它等于 ![\simb+1 ](./p__sim_b_+_1_.png) 。*b* 如果和 ![\simb ](./p__sim_b_.png) 进行按位与运算,那么会得到 *0*,但是当 ![\simb ](./p__sim_b_.png) 增加 *1* 之后,最低位的连续的 *1* 都变为 *0*,而最低位的 *0* 变为 *1*,对应到 *b* 中即为最低位的 *1*,因此当 *b* 和 ![\simb+1 ](./p__sim_b_+_1_.png) 进行按位与运算时,只有最低位的 *1* 会被保留;
- 当我们得到这个最低位的 *1* 时,我们可以通过一些语言自带的函数得到这个最低位的 *1* 究竟是第几位(即 *i* 值),具体可以参考下面的代码;
- 我们可以用 *b* 和最低位的 *1* 进行按位异或运算,就可以将其从 *b* 中去除,这样就可以枚举下一个 *1*。同样地,我们也可以用 *b**b-1* 进行按位与运算达到相同的效果,读者可以自行尝试推导。
实际上,方法二中整体的递归 + 回溯的框架与方法一是一致的。不同的仅仅是我们将一个数组「压缩」成了一个数而已。
**代码**
```C++ [sol2-C++]
class Solution {
private:
int line[9];
int column[9];
int block[3][3];
bool valid;
vector<pair<int, int>> spaces;
public:
void flip(int i, int j, int digit) {
line[i] ^= (1 << digit);
column[j] ^= (1 << digit);
block[i / 3][j / 3] ^= (1 << digit);
}
void dfs(vector<vector<char>>& board, int pos) {
if (pos == spaces.size()) {
valid = true;
return;
}
auto [i, j] = spaces[pos];
int mask = ~(line[i] | column[j] | block[i / 3][j / 3]) & 0x1ff;
for (; mask && !valid; mask &= (mask - 1)) {
int digitMask = mask & (-mask);
int digit = __builtin_ctz(digitMask);
flip(i, j, digit);
board[i][j] = digit + '0' + 1;
dfs(board, pos + 1);
flip(i, j, digit);
}
}
void solveSudoku(vector<vector<char>>& board) {
memset(line, 0, sizeof(line));
memset(column, 0, sizeof(column));
memset(block, 0, sizeof(block));
valid = false;
for (int i = 0; i < 9; ++i) {
for (int j = 0; j < 9; ++j) {
if (board[i][j] == '.') {
spaces.emplace_back(i, j);
}
else {
int digit = board[i][j] - '0' - 1;
flip(i, j, digit);
}
}
}
dfs(board, 0);
}
};
```
```Java [sol2-Java]
class Solution {
private int[] line = new int[9];
private int[] column = new int[9];
private int[][] block = new int[3][3];
private boolean valid = false;
private List<int[]> spaces = new ArrayList<int[]>();
public void solveSudoku(char[][] board) {
for (int i = 0; i < 9; ++i) {
for (int j = 0; j < 9; ++j) {
if (board[i][j] == '.') {
spaces.add(new int[]{i, j});
} else {
int digit = board[i][j] - '0' - 1;
flip(i, j, digit);
}
}
}
dfs(board, 0);
}
public void dfs(char[][] board, int pos) {
if (pos == spaces.size()) {
valid = true;
return;
}
int[] space = spaces.get(pos);
int i = space[0], j = space[1];
int mask = ~(line[i] | column[j] | block[i / 3][j / 3]) & 0x1ff;
for (; mask != 0 && !valid; mask &= (mask - 1)) {
int digitMask = mask & (-mask);
int digit = Integer.bitCount(digitMask - 1);
flip(i, j, digit);
board[i][j] = (char) (digit + '0' + 1);
dfs(board, pos + 1);
flip(i, j, digit);
}
}
public void flip(int i, int j, int digit) {
line[i] ^= (1 << digit);
column[j] ^= (1 << digit);
block[i / 3][j / 3] ^= (1 << digit);
}
}
```
```Python [sol2-Python3]
class Solution:
def solveSudoku(self, board: List[List[str]]) -> None:
def flip(i: int, j: int, digit: int):
line[i] ^= (1 << digit)
column[j] ^= (1 << digit)
block[i // 3][j // 3] ^= (1 << digit)
def dfs(pos: int):
nonlocal valid
if pos == len(spaces):
valid = True
return
i, j = spaces[pos]
mask = ~(line[i] | column[j] | block[i // 3][j // 3]) & 0x1ff
while mask:
digitMask = mask & (-mask)
digit = bin(digitMask).count("0") - 1
flip(i, j, digit)
board[i][j] = str(digit + 1)
dfs(pos + 1)
flip(i, j, digit)
mask &= (mask - 1)
if valid:
return
line = [0] * 9
column = [0] * 9
block = [[0] * 3 for _ in range(3)]
valid = False
spaces = list()
for i in range(9):
for j in range(9):
if board[i][j] == ".":
spaces.append((i, j))
else:
digit = int(board[i][j]) - 1
flip(i, j, digit)
dfs(0)
```
```Golang [sol2-Golang]
func solveSudoku(board [][]byte) {
var line, column [9]int
var block [3][3]int
var spaces [][2]int
flip := func(i, j int, digit byte) {
line[i] ^= 1 << digit
column[j] ^= 1 << digit
block[i/3][j/3] ^= 1 << digit
}
for i, row := range board {
for j, b := range row {
if b == '.' {
spaces = append(spaces, [2]int{i, j})
} else {
digit := b - '1'
flip(i, j, digit)
}
}
}
var dfs func(int) bool
dfs = func(pos int) bool {
if pos == len(spaces) {
return true
}
i, j := spaces[pos][0], spaces[pos][1]
mask := 0x1ff &^ uint(line[i]|column[j]|block[i/3][j/3]) // 0x1ff 即二进制的 9 个 1
for ; mask > 0; mask &= mask - 1 { // 最右侧的 1 置为 0
digit := byte(bits.TrailingZeros(mask))
flip(i, j, digit)
board[i][j] = digit + '1'
if dfs(pos + 1) {
return true
}
flip(i, j, digit)
}
return false
}
dfs(0)
}
```
```C [sol2-C]
int line[9];
int column[9];
int block[3][3];
bool valid;
int* spaces[81];
int spacesSize;
void flip(int i, int j, int digit) {
line[i] ^= (1 << digit);
column[j] ^= (1 << digit);
block[i / 3][j / 3] ^= (1 << digit);
}
void dfs(char** board, int pos) {
if (pos == spacesSize) {
valid = true;
return;
}
int i = spaces[pos][0], j = spaces[pos][1];
int mask = ~(line[i] | column[j] | block[i / 3][j / 3]) & 0x1ff;
for (; mask && !valid; mask &= (mask - 1)) {
int digitMask = mask & (-mask);
int digit = __builtin_ctz(digitMask);
flip(i, j, digit);
board[i][j] = digit + '0' + 1;
dfs(board, pos + 1);
flip(i, j, digit);
}
}
void solveSudoku(char** board, int boardSize, int* boardColSize) {
memset(line, 0, sizeof(line));
memset(column, 0, sizeof(column));
memset(block, 0, sizeof(block));
valid = false;
spacesSize = 0;
for (int i = 0; i < 9; ++i) {
for (int j = 0; j < 9; ++j) {
if (board[i][j] == '.') {
spaces[spacesSize] = malloc(sizeof(int) * 2);
spaces[spacesSize][0] = i;
spaces[spacesSize++][1] = j;
} else {
int digit = board[i][j] - '0' - 1;
flip(i, j, digit);
}
}
}
dfs(board, 0);
}
```
#### 方法三:枚举优化
**思路与算法**
我们可以顺着方法二的思路继续优化下去:
- 如果一个空白格只有唯一的数可以填入,也就是其对应的 *b* 值和 *b-1* 进行按位与运算后得到 *0*(即 *b* 中只有一个二进制位为 *1*)。此时,我们就可以确定这个空白格填入的数,而不用等到递归时再去处理它。
这样一来,我们可以不断地对整个数独进行遍历,将可以唯一确定的空白格全部填入对应的数。随后我们再使用与方法二相同的方法对剩余无法唯一确定的空白格进行递归 + 回溯。
**代码**
```C++ [sol3-C++]
class Solution {
private:
int line[9];
int column[9];
int block[3][3];
bool valid;
vector<pair<int, int>> spaces;
public:
void flip(int i, int j, int digit) {
line[i] ^= (1 << digit);
column[j] ^= (1 << digit);
block[i / 3][j / 3] ^= (1 << digit);
}
void dfs(vector<vector<char>>& board, int pos) {
if (pos == spaces.size()) {
valid = true;
return;
}
auto [i, j] = spaces[pos];
int mask = ~(line[i] | column[j] | block[i / 3][j / 3]) & 0x1ff;
for (; mask && !valid; mask &= (mask - 1)) {
int digitMask = mask & (-mask);
int digit = __builtin_ctz(digitMask);
flip(i, j, digit);
board[i][j] = digit + '0' + 1;
dfs(board, pos + 1);
flip(i, j, digit);
}
}
void solveSudoku(vector<vector<char>>& board) {
memset(line, 0, sizeof(line));
memset(column, 0, sizeof(column));
memset(block, 0, sizeof(block));
valid = false;
for (int i = 0; i < 9; ++i) {
for (int j = 0; j < 9; ++j) {
if (board[i][j] != '.') {
int digit = board[i][j] - '0' - 1;
flip(i, j, digit);
}
}
}
while (true) {
int modified = false;
for (int i = 0; i < 9; ++i) {
for (int j = 0; j < 9; ++j) {
if (board[i][j] == '.') {
int mask = ~(line[i] | column[j] | block[i / 3][j / 3]) & 0x1ff;
if (!(mask & (mask - 1))) {
int digit = __builtin_ctz(mask);
flip(i, j, digit);
board[i][j] = digit + '0' + 1;
modified = true;
}
}
}
}
if (!modified) {
break;
}
}
for (int i = 0; i < 9; ++i) {
for (int j = 0; j < 9; ++j) {
if (board[i][j] == '.') {
spaces.emplace_back(i, j);
}
}
}
dfs(board, 0);
}
};
```
```Java [sol3-Java]
class Solution {
private int[] line = new int[9];
private int[] column = new int[9];
private int[][] block = new int[3][3];
private boolean valid = false;
private List<int[]> spaces = new ArrayList<int[]>();
public void solveSudoku(char[][] board) {
for (int i = 0; i < 9; ++i) {
for (int j = 0; j < 9; ++j) {
if (board[i][j] != '.') {
int digit = board[i][j] - '0' - 1;
flip(i, j, digit);
}
}
}
while (true) {
boolean modified = false;
for (int i = 0; i < 9; ++i) {
for (int j = 0; j < 9; ++j) {
if (board[i][j] == '.') {
int mask = ~(line[i] | column[j] | block[i / 3][j / 3]) & 0x1ff;
if ((mask & (mask - 1)) == 0) {
int digit = Integer.bitCount(mask - 1);
flip(i, j, digit);
board[i][j] = (char) (digit + '0' + 1);
modified = true;
}
}
}
}
if (!modified) {
break;
}
}
for (int i = 0; i < 9; ++i) {
for (int j = 0; j < 9; ++j) {
if (board[i][j] == '.') {
spaces.add(new int[]{i, j});
}
}
}
dfs(board, 0);
}
public void dfs(char[][] board, int pos) {
if (pos == spaces.size()) {
valid = true;
return;
}
int[] space = spaces.get(pos);
int i = space[0], j = space[1];
int mask = ~(line[i] | column[j] | block[i / 3][j / 3]) & 0x1ff;
for (; mask != 0 && !valid; mask &= (mask - 1)) {
int digitMask = mask & (-mask);
int digit = Integer.bitCount(digitMask - 1);
flip(i, j, digit);
board[i][j] = (char) (digit + '0' + 1);
dfs(board, pos + 1);
flip(i, j, digit);
}
}
public void flip(int i, int j, int digit) {
line[i] ^= (1 << digit);
column[j] ^= (1 << digit);
block[i / 3][j / 3] ^= (1 << digit);
}
}
```
```Python [sol3-Python3]
class Solution:
def solveSudoku(self, board: List[List[str]]) -> None:
def flip(i: int, j: int, digit: int):
line[i] ^= (1 << digit)
column[j] ^= (1 << digit)
block[i // 3][j // 3] ^= (1 << digit)
def dfs(pos: int):
nonlocal valid
if pos == len(spaces):
valid = True
return
i, j = spaces[pos]
mask = ~(line[i] | column[j] | block[i // 3][j // 3]) & 0x1ff
while mask:
digitMask = mask & (-mask)
digit = bin(digitMask).count("0") - 1
flip(i, j, digit)
board[i][j] = str(digit + 1)
dfs(pos + 1)
flip(i, j, digit)
mask &= (mask - 1)
if valid:
return
line = [0] * 9
column = [0] * 9
block = [[0] * 3 for _ in range(3)]
valid = False
spaces = list()
for i in range(9):
for j in range(9):
if board[i][j] != ".":
digit = int(board[i][j]) - 1
flip(i, j, digit)
while True:
modified = False
for i in range(9):
for j in range(9):
if board[i][j] == ".":
mask = ~(line[i] | column[j] | block[i // 3][j // 3]) & 0x1ff
if not (mask & (mask - 1)):
digit = bin(mask).count("0") - 1
flip(i, j, digit)
board[i][j] = str(digit + 1)
modified = True
if not modified:
break
for i in range(9):
for j in range(9):
if board[i][j] == ".":
spaces.append((i, j))
dfs(0)
```
```Golang [sol3-Golang]
func solveSudoku(board [][]byte) {
var line, column [9]int
var block [3][3]int
var spaces [][2]int
flip := func(i, j int, digit byte) {
line[i] ^= 1 << digit
column[j] ^= 1 << digit
block[i/3][j/3] ^= 1 << digit
}
for i, row := range board {
for j, b := range row {
if b != '.' {
digit := b - '1'
flip(i, j, digit)
}
}
}
for {
modified := false
for i, row := range board {
for j, b := range row {
if b != '.' {
continue
}
mask := 0x1ff &^ uint(line[i]|column[j]|block[i/3][j/3])
if mask&(mask-1) == 0 { // mask 的二进制表示仅有一个 1
digit := byte(bits.TrailingZeros(mask))
flip(i, j, digit)
board[i][j] = digit + '1'
modified = true
}
}
}
if !modified {
break
}
}
for i, row := range board {
for j, b := range row {
if b == '.' {
spaces = append(spaces, [2]int{i, j})
}
}
}
var dfs func(int) bool
dfs = func(pos int) bool {
if pos == len(spaces) {
return true
}
i, j := spaces[pos][0], spaces[pos][1]
mask := 0x1ff &^ uint(line[i]|column[j]|block[i/3][j/3]) // 0x1ff 即二进制的 9 个 1
for ; mask > 0; mask &= mask - 1 { // 最右侧的 1 置为 0
digit := byte(bits.TrailingZeros(mask))
flip(i, j, digit)
board[i][j] = digit + '1'
if dfs(pos + 1) {
return true
}
flip(i, j, digit)
}
return false
}
dfs(0)
}
```
```C [sol3-C]
int line[9];
int column[9];
int block[3][3];
bool valid;
int* spaces[81];
int spacesSize;
void flip(int i, int j, int digit) {
line[i] ^= (1 << digit);
column[j] ^= (1 << digit);
block[i / 3][j / 3] ^= (1 << digit);
}
void dfs(char** board, int pos) {
if (pos == spacesSize) {
valid = true;
return;
}
int i = spaces[pos][0], j = spaces[pos][1];
int mask = ~(line[i] | column[j] | block[i / 3][j / 3]) & 0x1ff;
for (; mask && !valid; mask &= (mask - 1)) {
int digitMask = mask & (-mask);
int digit = __builtin_ctz(digitMask);
flip(i, j, digit);
board[i][j] = digit + '0' + 1;
dfs(board, pos + 1);
flip(i, j, digit);
}
}
void solveSudoku(char** board, int boardSize, int* boardColSize) {
memset(line, 0, sizeof(line));
memset(column, 0, sizeof(column));
memset(block, 0, sizeof(block));
valid = false;
spacesSize = 0;
for (int i = 0; i < 9; ++i) {
for (int j = 0; j < 9; ++j) {
if (board[i][j] != '.') {
int digit = board[i][j] - '0' - 1;
flip(i, j, digit);
}
}
}
while (true) {
int modified = false;
for (int i = 0; i < 9; ++i) {
for (int j = 0; j < 9; ++j) {
if (board[i][j] == '.') {
int mask = ~(line[i] | column[j] | block[i / 3][j / 3]) & 0x1ff;
if (!(mask & (mask - 1))) {
int digit = __builtin_ctz(mask);
flip(i, j, digit);
board[i][j] = digit + '0' + 1;
modified = true;
}
}
}
}
if (!modified) {
break;
}
}
for (int i = 0; i < 9; ++i) {
for (int j = 0; j < 9; ++j) {
if (board[i][j] == '.') {
spaces[spacesSize] = malloc(sizeof(int) * 2);
spaces[spacesSize][0] = i;
spaces[spacesSize++][1] = j;
}
}
}
dfs(board, 0);
}
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 226 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 511 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 539 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 325 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 660 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 789 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 781 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 556 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 876 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 686 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 367 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 769 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 694 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 899 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 925 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 487 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 703 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 461 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 441 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 480 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 363 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 B

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>Code</artifactId>
<groupId>com.code</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>LintCode</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
</project>

View File

@ -1,29 +0,0 @@
package com.code.lint.entiy;
/**
* @Author: hyy
* @Date: 2020-01-25 23:45
*/
public class Interval {
int start, end;
Interval(int start, int end) {
this.start = start;
this.end = end;
}
public int getStart() {
return start;
}
public int getEnd() {
return end;
}
public void setStart(int start) {
this.start = start;
}
public void setEnd(int end) {
this.end = end;
}
}

View File

@ -1,14 +0,0 @@
package com.code.lint.entiy;
/**
* @Author: hyy
* @Date: 2020-01-26 01:37
*/
public class ListNode {
public int val;
public ListNode next;
public ListNode(int x) {
val = x;
}
}

View File

@ -1,12 +0,0 @@
package com.code.lint.entiy;
/**
* @Author: hyy
* @Date: 2020-02-11 10:10
*/
public class SVNRepo {
public static boolean isBadVersion(int k) {
return false;
}
}

View File

@ -1,15 +0,0 @@
package com.code.lint.entiy;
/**
* @Author: hyy
* @Date: 2020-01-27 00:05
*/
public class TreeNode {
public int val;
public TreeNode left, right;
public TreeNode(int val) {
this.val = val;
this.left = this.right = null;
}
}

View File

@ -1,40 +0,0 @@
package com.code.lint.util;
import entiy.TreeNode;
import java.util.ArrayList;
import java.util.List;
/**
* @Author: hyy
* @Date: 2020-01-27 16:08
*/
public class CreateTree {
public static TreeNode createTree(String str){
TreeNode root = null;
List<TreeNode> treeNodes = new ArrayList<>();
String[] val = str.split(",");
root = new TreeNode(Integer.parseInt(val[0]));
treeNodes.add(root);
int j=0;
for (int i=1;i<val.length;i++){
TreeNode temp;
if(val[i].equals("#")){
temp = null;
}else{
temp = new TreeNode(Integer.parseInt(val[i]));
treeNodes.add(temp);
}
if(i%2==0){
treeNodes.get(j).right = temp;
j++;
}else{
treeNodes.get(j).left = temp;
}
}
return root;
}
}

View File

@ -1,9 +0,0 @@
package com.code.lint.y2020.m01.d25;
/**
* @Author: hyy
* @Date: 2020-01-25 19:28
*/
public class Aplusb {
}

View File

@ -1,39 +0,0 @@
package com.code.lint.y2020.m01.d25;
import entiy.Interval;
import java.util.List;
/**
* @Author: hyy
* @Date: 2020-01-25 23:42
*/
public class CanAttendMeetings {
/**
* @param intervals: an array of meeting time intervals
* @return: if a person could attend all meetings
*/
public boolean canAttendMeetings(List<Interval> intervals) {
// Write your code here
for (int i = 0;i<intervals.size();i++){
for (int j=i+1;j<intervals.size();j++){
if(intervals.get(i).getStart()>=intervals.get(j).getStart()){
if(intervals.get(i).getStart()>=intervals.get(j).getEnd()){
Interval temp = intervals.get(i);
intervals.set(i, intervals.get(j));
}else{
return false;
}
}else{
if(intervals.get(i).getEnd()>intervals.get(j).getStart()){
return false;
}
}
}
}
return true;
}
public static void main(String[] args) {
}
}

View File

@ -1,23 +0,0 @@
package com.code.lint.y2020.m01.d25;
/**
* @Author: hyy
* @Date: 2020-01-25 21:58
*/
public class FirstUniqChar {
/**
* @param str: str: the given string
* @return: char: the first unique character in a given string
*/
public char firstUniqChar(String str) {
String temp;
for (int i = 0; i < str.length(); i++){
if(str.indexOf(str.charAt(i))==str.lastIndexOf(str.charAt(i))){
return str.charAt(i);
}
}
return '0';
}
}

View File

@ -1,20 +0,0 @@
package com.code.lint.y2020.m01.d25;
import java.util.regex.Pattern;
/**
* @Author: hyy
* @Date: 2020-01-25 21:59
*/
public class IsLegalIdentifier {
/**
* @param str: The identifier need to be judged.
* @return: Return if str is a legal identifier.
*/
public boolean isLegalIdentifier(String str) {
String pa = "^[a-zA-Z][a-z0-9A-Z_]+";
return Pattern.matches(pa,str);
}
}

View File

@ -1,23 +0,0 @@
package com.code.lint.y2020.m01.d25;
/**
* @Author: hyy
* @Date: 2020-01-25 21:58
*/
public class IsUnique {
/**
* @param str: A string
* @return: a boolean
*/
public boolean isUnique(String str) {
// write your code here
for (int i = 1;i<str.length();i++){
if(str.indexOf(str.charAt(i))!=str.lastIndexOf(str.charAt(i))){
return false;
}
}
return true;
}
}

View File

@ -1,18 +0,0 @@
package com.code.lint.y2020.m01.d25;
/**
* @Author: hyy
* @Date: 2020-01-25 19:50
*/
public class Main {
public static void main(String[] args) {
Solution solution = new Solution();
// System.out.println(solution.reverseWords(" a b"));
// System.out.println(solution.firstUniqChar("aabc"));
// System.out.println(solution.firstUniqChar("abaccdeff"));
// System.out.println(solution.isLegalIdentifier("LintCode"));
// System.out.println(solution.mostFrequentlyAppearingLetters("ABCabcA"));
System.out.println(solution.count("WfaOIUZeTuQhIArgJuSgFufHBDoONlOVkKzXNwbDNXwD,EemZNuUovYHqKIaQBTZWUJinpNm,OX.DQPfHLNgedBUlGrHMgvoVw,sRicWxN.uNmULoHkMumuA mtemWcWPoUeZZdclZDYpbWY.OpAIBAVtJWfvTYzZtJowzcGizConWSUmZQHfnivsIedejNMtdiBTLfepfz,KTXTodw zNiIzFYSPuwPZLkhPkyvuxJinQHsPRfqDJGEECWhOiE.FCfexqGIpdlTTXgLvBxeUIuN.LPjQZCnH GJUlhCKDSZ"));
}
}

View File

@ -1,33 +0,0 @@
package com.code.lint.y2020.m01.d25;
import java.util.HashMap;
import java.util.Map;
/**
* @Author: hyy
* @Date: 2020-01-25 21:59
*/
public class MostFrequentlyAppearingLetters {
/**
* @param str: the str
* @return: the sum that the letter appears the most
*/
public int mostFrequentlyAppearingLetters(String str) {
// Write your code here.
Map<Character, Integer> map = new HashMap<>();
int max = 1;
for (int i = 0 ;i<str.length();i++){
if(map.containsKey(str.charAt(i))){
map.put(str.charAt(i),map.get(str.charAt(i))+1);
if(map.get(str.charAt(i))>max){
max = map.get(str.charAt(i));
}
}else{
map.put(str.charAt(i),1);
}
}
return max;
}
}

View File

@ -1,38 +0,0 @@
package com.code.lint.y2020.m01.d25;
/**
* @Author: hyy
* @Date: 2020-01-25 22:40
*/
public class MultiSort {
/**
* @param array: the input array
* @return: the sorted array
*/
public static int[][] multiSort(int[][] array) {
// Write your code here
for (int i = 0;i<array.length;i++){
for (int j=i+1;j<array.length;j++){
if(array[i][1]<array[j][1]){
int[] temp = array[i];
array[i] = array[j];
array[j] = temp;
}else if(array[i][1]==array[j][1]){
if(array[i][0]>array[j][0]){
int[] temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
}
return array;
}
public static void main(String[] args) {
int[][] array = new int[][]{{7,66},{4,77},{3,63},{5,81},{1,88},{9,86},{6,88},{2,82},{8,55},{10,95}};
array = multiSort(array);
System.out.println(array.toString());
}
}

View File

@ -1,46 +0,0 @@
package com.code.lint.y2020.m01.d25;
import java.util.ArrayList;
import java.util.List;
/**
* @Author: hyy
* @Date: 2020-01-25 19:12
*/
public class NarcissisticNumbers {
public static void main(String[] args) {
for (Integer i:getNarcissisticNumbers(3)
) {
System.out.println(i);
}
}
/**
* @param n: The number of digits
* @return: All narcissistic numbers with n digits
*/
public static List<Integer> getNarcissisticNumbers(int n) {
// write your code here
List<Integer> nums = new ArrayList<>();
int min = (int)Math.pow(10,n-1);
if(n==1){
min=0;
}
int max = (int)Math.pow(10,n);
for (int i = min; i < max; i++){
int temp = i;
int j = 0;
int sum = 0;
while(temp>10){
sum += Math.pow(temp % 10,n);
temp /= 10;
j++;
}
sum += Math.pow(temp % 10,n);
if(sum==i){
nums.add(i);
}
}
return nums;
}
}

View File

@ -1,31 +0,0 @@
package com.code.lint.y2020.m01.d25;
/**
* @Author: hyy
* @Date: 2020-01-25 21:57
*/
public class ReverseWords {
/**
* @param s: A string
* @return: A string
*/
public String reverseWords(String s) {
// write your code here
if(s.equals("")) {
return s;
}
String[] strings = s.split(" ");
s = "";
for (String str:strings
) {
if(!str.equals("")){
s = str + " " + s;
}
}
if(!s.equals("")){
s = s.substring(0,s.length()-1);
}
return s;
}
}

View File

@ -1,32 +0,0 @@
package com.code.lint.y2020.m01.d25;
/**
* @Author: hyy
* @Date: 2020-01-25 18:51
*/
public class RotateString {
public static void main(String[] args) {
String str="abcdefg";
int offset = 3;
rotateString(str.toCharArray(),offset);
}
/**
* @param str: An array of char
* @param offset: An integer
* @return: nothing
*/
public static void rotateString(char[] str, int offset) {
if(str.length == 0 || offset == 0){
return;
}
offset = offset%str.length;//实际偏移量
for(int i = 0;i<offset; i++){
char temp = str[str.length-1];
for(int j = str.length-1;j>0;j--){
str[j] = str[j-1];
}
str[0] = temp;
}
}
}

View File

@ -1,17 +0,0 @@
package com.code.lint.y2020.m01.d25;
/**
* @Author: hyy
* @Date: 2020-01-25 19:46
*/
public class RoundArea {
/**
* @param r: the given radius
* @return: the area of the given circle
*/
public double getArea(double r) {
// write your code here
return 3.14 * r * r;
}
}

View File

@ -1,24 +0,0 @@
package com.code.lint.y2020.m01.d25;
/**
* @Author: hyy
* @Date: 2020-01-25 22:59
*/
public class SearchInsert {
/**
* @param A: an integer sorted array
* @param target: an integer to be inserted
* @return: An integer
*/
public int searchInsert(int[] A, int target) {
// write your code here
int i=0;
for(i=0;i<A.length;i++){
if(A[i]>=target) {
break;
}
}
return i;
}
}

View File

@ -1,35 +0,0 @@
package com.code.lint.y2020.m01.d25;
import java.util.regex.Pattern;
/**
* @Author: hyy
* @Date: 2020-01-25 19:50
*/
public class Solution {
/**
* @param s: the article
* @return: the number of letters that are illegal
*/
public int count(String s) {
// Write your code here.
int num = 0;
String[] sentence = s.split("\\.");
for (String str:sentence) {
if(!Pattern.matches("^[A-Z].*",str.trim())){
num++;
}
String[] words = str.split(" |,");
for(String word:words){
for (int i=1;i<word.length();i++){
if(Pattern.matches("[A-Z]",""+word.charAt(i))){
num++;
}
}
}
}
return num;
}
}

View File

@ -1,18 +0,0 @@
package com.code.lint.y2020.m01.d25;
/**
* @Author: hyy
* @Date: 2020-01-25 21:58
*/
public class StrStr {
/**
* @param source:
* @param target:
* @return: return the index
*/
public int strStr(String source, String target) {
return source.indexOf(target);
}
}

View File

@ -1,38 +0,0 @@
package com.code.lint.y2020.m01.d25;
/**
* 描述
*
* 给一个整数数组找到两个数使得他们的和等于一个给定的数 target
* 你需要实现的函数twoSum需要返回这两个数的下标, 并且第一个下标小于第二个下标注意这里下标的范围是 0 n-1
*/
public class TwoSum{
public static void main(String[] args){
int[] numbers = {2, 7, 11, 15};
int[] result = twoSum(numbers,9);
System.out.print("["+result[0]+","+result[1]+"]");
}
/**
* @param numbers: An array of Integer
* @param target: target = numbers[index1] + numbers[index2]
* @return: [index1, index2] (index1 < index2)
*/
public static int[] twoSum(int[] numbers, int target) {
/**
* @param numbers: An array of Integer
* @param target: target = numbers[index1] + numbers[index2]
* @return: [index1, index2] (index1 < index2)
*/
int[] index = new int[2];
for(int i = 0; i < numbers.length; i++){
for(int j=i+1;j<numbers.length;j++){
if(numbers[i]+numbers[j]==target){
index[0]=i;
index[1]=j;
return index;
}
}
}
return index;
}
}

View File

@ -1,44 +0,0 @@
package com.code.lint.y2020.m01.d26;
import entiy.ListNode;
/**
*
* 466. 链表节点计数
*
* 计算链表中有多少个节点.
* 样例
*
* 样例 1:
* 输入: 1->3->5->null
* 输出: 3
*
* 样例解释:
* 返回链表中结点个数也就是链表的长度.
*
* 样例 2:
* 输入: null
* 输出: 0
*
* 样例解释:
* 空链表长度为0
*
* @Author: hyy
* @Date: 2020-01-26 01:52
*/
public class CountNodes {
/**
* @param head: the first node of linked list.
* @return: An integer
*/
public int countNodes(ListNode head) {
// write your code here
int num=0;
while (head!=null){
num++;
head = head.next;
}
return num;
}
}

View File

@ -1,25 +0,0 @@
package com.code.lint.y2020.m01.d26;
import entiy.ListNode;
/**
* @Author: hyy
* @Date: 2020-01-26 02:53
*/
public class CountNodesII {
/**
* @param head:
* @return: nothing
*/
public int countNodesII(ListNode head) {
int num = 0;
while (head!=null){
if(head.val>0&&head.val%2>0){
num++;
}
head = head.next;
}
return num;
}
}

View File

@ -1,36 +0,0 @@
package com.code.lint.y2020.m01.d26;
/**
* @Author: hyy
* @Date: 2020-01-26 00:04
*/
public class Deduplication {
/**
* @param nums: an array of integers
* @return: the number of unique integers
*/
public static int deduplication(int[] nums) {
// write your code here
int num = nums.length;
for (int i=0;i<num;i++){
for (int j=i+1;j<num;j++){
while(nums[i]==nums[j]&&j<num){
int temp = nums[j];
nums[j] = nums[num-1];
nums[num-1] = temp;
num--;
}
}
}
return num;
}
public static void main(String[] args) {
int[] nums = new int[]{1,3,1,4,4,2};
int n = deduplication(nums);
for(int i=0;i<n;i++){
System.out.println(nums[i]);
}
}
}

View File

@ -1,48 +0,0 @@
package com.code.lint.y2020.m01.d26;
import entiy.ListNode;
/**
* @Author: hyy
* @Date: 2020-01-26 02:33
*/
public class DeleteNode {
/**
* @param head: The first node of linked list
* @param n: the start index
* @param m: the end node
* @return: A ListNode
*/
public ListNode deleteNode(ListNode head, int n, int m) {
// Write your code here
int num=0;
ListNode temp = head;
while (head!=null){
num++;
if(num>n){
while (num<=m+1){
if(head.next!=null){
head = head.next;
temp = head;
}else{
temp = null;
}
num++;
}
}
if(num==n){
while (num<=m){
num++;
if(head.next!=null){
head.next = head.next.next;
} else {
break;
}
}
}
head=head.next;
}
return temp;
}
}

View File

@ -1,35 +0,0 @@
package com.code.lint.y2020.m01.d26;
/**
* @Author: hyy
* @Date: 2020-01-26 01:32
*/
public class Depress {
/**
* @param m: the limit
* @param k: the sum of choose
* @param arr: the array
* @return: yes or no
*/
public String depress(int m, int k, int[] arr) {
for (int i=0;i<arr.length;i++){
for (int j=0;j<arr.length;j++){
if(arr[i]<arr[j]){
int temp = arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
}
int sum=0;
for (int i=0;i<k;i++){
sum+=arr[i];
}
if(sum<m){
return "yes";
}else{
return "no";
}
}
}

View File

@ -1,59 +0,0 @@
package com.code.lint.y2020.m01.d26;
import entiy.ListNode;
/**
*
* 219. 在排序链表中插入一个节点
* 中文
* English
*
* 在链表中插入一个节点
* 样例
*
* 样例 1
*
* 输入head = 1->4->6->8->null, val = 5
* 输出1->4->5->6->8->null
*
* 样例 2
*
* 输入head = 1->null, val = 2
* 输出1->2->null
*
* @Author: hyy
* @Date: 2020-01-26 01:58
*/
public class InsertNode {
/**
* @param head: The head of linked list.
* @param val: An integer.
* @return: The head of new linked list.
*/
public ListNode insertNode(ListNode head, int val) {
// write your code here
if(head==null){
ListNode newNode = new ListNode(val);
newNode.next = null;
return newNode;
}
if(val<=head.val){
ListNode newNode = new ListNode(val);
newNode.next = head;
return newNode;
}
ListNode temp = head;
while(val>head.val){
if(head.next!=null&&val>head.next.val){
head = head.next;
}else{
ListNode newNode = new ListNode(val);
newNode.next = head.next;
head.next = newNode;
break;
}
}
return temp;
}
}

View File

@ -1,39 +0,0 @@
package com.code.lint.y2020.m01.d26;
import entiy.ListNode;
import java.util.ArrayList;
import java.util.List;
/**
* @Author: hyy
* @Date: 2020-01-26 01:36
*/
public class MiddleNode {
/**
* @param head: the head of linked list.
* @return: a middle node of the linked list
*/
public ListNode middleNode(ListNode head) {
// write your code here
int num=0;
int index;
if(head==null){
return head;
}
List<ListNode> listNodes = new ArrayList<>();
ListNode next = head.next;
while (head!=null){
num++;
listNodes.add(head);
head = head.next;
}
if(num%2==0){
index = num/2-1;
}else {
index = num/2;
}
return listNodes.get(index);
}
}

View File

@ -1,29 +0,0 @@
package com.code.lint.y2020.m01.d26;
import entiy.ListNode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @Author: hyy
* @Date: 2020-01-26 02:25
*/
public class ReverseStore {
/**
* @param head: the given linked list
* @return: the array that store the values in reverse order
*/
public List<Integer> reverseStore(ListNode head) {
// write your code here
List<Integer> list = new ArrayList<>();
while (head!=null){
list.add(head.val);
head = head.next;
}
Collections.reverse(list);
return list;
}
}

View File

@ -1,25 +0,0 @@
package com.code.lint.y2020.m01.d26;
/**
* @Author: hyy
* @Date: 2020-01-26 00:39
*/
public class SortIntegers {
/**
* @param A: an integer array
* @return: nothing
*/
public void sortIntegers(int[] A) {
// write your code here
for (int i=0;i<A.length;i++){
for (int j=0;j<A.length;j++){
if(A[i]<A[j]){
int temp = A[i];
A[i]=A[j];
A[j]=temp;
}
}
}
}
}

View File

@ -1,51 +0,0 @@
package com.code.lint.y2020.m01.d27;
import entiy.TreeNode;
import util.CreateTree;
import java.util.ArrayList;
import java.util.List;
/**
* @Author: hyy
* @Date: 2020-01-27 00:32
*/
public class BinaryTreePathSum {
/*
* @param root: the root of binary tree
* @param target: An integer
* @return: all valid paths
*/
static List<List<Integer>> result = new ArrayList<>();
static List<Integer> path = new ArrayList<>();
static int sum = 0;
public static List<List<Integer>> binaryTreePathSum(TreeNode root, int target) {
// write your code here
if(root==null){
return new ArrayList<>();
}
path.add(root.val);
sum += root.val;
if(root.left==null&&root.right==null){
if(sum==target){
result.add(new ArrayList(path));
}
}
if(root.left!=null){
binaryTreePathSum(root.left,target);
}
if(root.right!=null){
binaryTreePathSum(root.right,target);
}
sum -= root.val;
path.remove(path.size()-1);
return result;
}
public static void main(String[] args) {
TreeNode root = CreateTree.createTree("1,1,1,3,4,4,3,#,#,1,#,5,7");
binaryTreePathSum(root,6);
}
}

View File

@ -1,79 +0,0 @@
package com.code.lint.y2020.m01.d27;
import entiy.TreeNode;
import util.CreateTree;
import java.util.ArrayList;
import java.util.List;
/**
* @Author: hyy
* @Date: 2020-01-27 17:05
*/
public class BinaryTreePaths {
/**
* @param root: the root of the binary tree
* @return: all root-to-leaf paths
*/
// public static List<String> binaryTreePaths(TreeNode root) {
// // write your code here
// if(root==null){
// return new ArrayList<>();
// }
// List<String> strings = new ArrayList<>();
// List<TreeNode> treeNodes = new ArrayList<>();
// List<Integer> trees = new ArrayList<>();
// while(root!=null||treeNodes.size()>0){
// while(root!=null){
// trees.add(root.val);
// treeNodes.add(root);
// if(root.left==null&&root.right==null){
// if(trees.size()==0){
// continue;
// }
// String str = "";
// for(Integer num:trees){
// str += num + "->";
// }
// strings.add(str.substring(0,str.length()-2));
// }
// root = root.left;
// }
// if(treeNodes.size()>0){
// root = treeNodes.get(treeNodes.size()-1).right;
// treeNodes.remove(treeNodes.size()-1);
//// trees.remove(trees.size()-1);
// }
// }
// return strings;
// }
static List<String> path = new ArrayList<>();
static List<Integer> nums = new ArrayList<>();
public static List<String> binaryTreePaths(TreeNode root) {
if(root==null){
return new ArrayList<>();
}
nums.add(root.val);
if(root.left==null&&root.right==null){
String str = "";
for (Integer num:nums){
str += num + "->";
}
str = str.substring(0,str.length()-2);
path.add(str);
}
if(root.left!=null){
binaryTreePaths(root.left);
}
if(root.right!=null){
binaryTreePaths(root.right);
}
nums.remove(nums.size()-1);
return path;
}
public static void main(String[] args) {
TreeNode root = CreateTree.createTree("1,2,3,#,5");
binaryTreePaths(root);
}
}

View File

@ -1,106 +0,0 @@
package com.code.lint.y2020.m01.d27;
import java.util.ArrayList;
import java.util.List;
/**
* error
* @Author: hyy
* @Date: 2020-01-27 19:06
*
* 1751. 牛郎织女
* cat-only-iconCAT 专属题目
*
* 又到了七夕节牛郎织女相约一起去一个n*m大小的迷宫maze里玩耍然而没过多久他们就倒霉地走散了现在给定由.,*,S,T组成的矩阵maze
* 其中.表示空地,*表示障碍物,S表示牛郎的位置 ,T表示织女的位置牛郎和织女都会试图寻找对方不停地在矩阵中走动(他们可以每次向上下左右四
* 个方向移动一格或者站着不动但是不能走到迷宫外面或者障碍物)请问他们是否有可能重逢?如果有可能返回True否则返回False
*
* 样例
*
* 样例1:
*
* 输入:
* [
* "S..*",
* "*.**",
* "...T"
* ]
* 输出: true
* 说明:
* 织女选择不动
* 牛郎行动路线(0,0)->(0,1)->(1,1)->(2,1)->(2,2)->(2,3)
*
* 样例2:
*
* 输入:
* [
* "S..*",
* "***.",
* "...T"
* ]
* 输出: false
* 说明
* 这两个人无论如何和碰不上了
*
* 注意事项
*
* 2<=n,m<=1000
*/
public class FindHer {
/**
* @param maze: the maze
* @return: Can they reunion?
*/
public boolean findHer(String[] maze) {
// Write your code here
List<String> strs = new ArrayList();
int[][] num = new int[strs.size()][strs.get(0).length()];
int x1=0,y1=0,x2=0,y2=0;
for(int i = 0; i < maze.length; i++){
strs.add(maze[i]);
int index1 = maze[i].indexOf("S");
if(index1>0){
x1=i;
y1=index1;
}
int index2 = maze[i].indexOf("T");
if(index2>0){
x2=i;
y2=index1;
}
}
for (int i = 0; i < num.length;i++){
for(int j=0;j<num[0].length;j++){
num[i][j]=0;
}
}
return isFind(strs,x1,y1,x2,y2,num);
}
boolean isFind(List<String> strs,int x1,int y1,int x2,int y2,int[][] num){
if(Math.abs(x1-x2)+Math.abs(y1-y2)==1){
return true;
}
boolean up = false;
boolean down = false;
boolean left = false;
boolean right = false;
if(x1-1>=0&&strs.get(x1-1).charAt(y1)=='.'&&num[x1-1][y1]==0){
num[x1-1][y1] = 1;
up = isFind(strs,x1-1,y1,x2,y2,num);
}
if(x1+1<strs.size()&&strs.get(x1+1).charAt(y1)=='.'&&num[x1+1][y1]==0){
num[x1+1][y1] = 1;
down = isFind(strs,x1+1,y1,x2,y2,num);
}
if(y1-1>=0&&strs.get(x1).charAt(y1-1)=='.'&&num[x1][y1-1]==0){
num[x1][y1-1] = 1;
left = isFind(strs,x1-1,y1,x2,y2,num);
}
if(y1+1<strs.get(0).length()&&strs.get(x1).charAt(y1+1)=='.'&&num[x1+1][y1]==0){
num[x1][y1+1] = 1;
right = isFind(strs,x1+1,y1,x2,y2,num);
}
return up||down||left||right;
}
}

View File

@ -1,30 +0,0 @@
package com.code.lint.y2020.m01.d27;
import entiy.TreeNode;
/**
* @Author: hyy
* @Date: 2020-01-27 19:22
*/
public class GetAns {
/**
* @param root: the root of the binary tree
* @return: the number of nodes
*/
int num = 0;
public int getAns(TreeNode root) {
// Write your code here
if(root==null){
return 0;
}
num++;
if(root.left!=null){
getAns(root.left);
}
if(root.right!=null){
getAns(root.right);
}
return num;
}
}

View File

@ -1,69 +0,0 @@
package com.code.lint.y2020.m01.d27;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
/**
* @Author: hyy
* @Date: 2020-01-27 19:26
*/
public class GetWays {
/**
* @param a: the n numbers
* @param k: the number of integers you can choose
* @return: how many ways that the sum of the k integers is a prime number
*/
static List<List<Integer>> result = new ArrayList<>();
static LinkedList<Integer> sum = new LinkedList<>();
public static int getWays(int[] a, int k) {
// Write your code here
List<Integer> date = new ArrayList<>();
int count = 0;
for (int i=0;i<a.length;i++){
date.add(a[i]);
}
getData(date,sum,k);
for (List<Integer> nums:result){
boolean flag = true;
int sum=0;
for (int num:nums){
sum+=num;
}
for (int i=2;i<sum;i++){
if(sum%i==0){
flag = false;
break;
}
}
if(flag){
count++;
}
}
return count;
}
public static void getData(List<Integer> date,LinkedList<Integer> sum,int length){
if(length==0){
result.add((List<Integer>)sum.clone());
return;
}
for (int i=0;i<date.size();i++){
sum.addLast(date.get(i));
List<Integer> newDate = new ArrayList<>(date);
for (int j=i;j>=0;j--){
newDate.remove(j);
}
getData(newDate,sum,length-1);
sum.removeLast();
}
}
public static void main(String[] args) {
int[] a = new int[]{3,7,12,19};
int k = 3;
getWays(a,k);
}
}

View File

@ -1,30 +0,0 @@
package com.code.lint.y2020.m01.d27;
import entiy.TreeNode;
import java.util.ArrayList;
import java.util.List;
/**
* @Author: hyy
* @Date: 2020-01-27 17:43
*/
public class InorderTraversal {
/**
* @param root: A Tree
* @return: Inorder in ArrayList which contains node values.
*/
List<Integer> trees = new ArrayList<>();
public List<Integer> inorderTraversal(TreeNode root) {
// write your code here
if(root==null){
return trees;
}
inorderTraversal(root.left);
trees.add(root.val);
inorderTraversal(root.right);
return trees;
}
}

View File

@ -1,38 +0,0 @@
package com.code.lint.y2020.m01.d27;
import entiy.TreeNode;
import java.util.ArrayList;
import java.util.List;
/**
* @Author: hyy
* @Date: 2020-01-27 17:37
*/
public class InvertBinaryTree {
/**
* @param root: a TreeNode, the root of the binary tree
* @return: nothing
*/
public void invertBinaryTree(TreeNode root) {
// write your code here
List<TreeNode> treeNodes = new ArrayList<>();
if(root==null){
return;
}
while (root!=null||treeNodes.size()>0){
while(root!=null){
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
treeNodes.add(root);
root = root.left;
}
if(treeNodes.size()>0){
root = treeNodes.get(treeNodes.size()-1).right;
treeNodes.remove(treeNodes.size()-1);
}
}
}
}

View File

@ -1,24 +0,0 @@
package com.code.lint.y2020.m01.d27;
import entiy.TreeNode;
/**
* @Author: hyy
* @Date: 2020-01-27 00:04
*/
public class MaxDepth {
/**
* @param root: The root of binary tree.
* @return: An integer
*/
public int maxDepth(TreeNode root) {
// write your code here
if(root==null){
return 0;
}
int left = maxDepth(root.left);
int right = maxDepth(root.right);
return left >= right ? left + 1 : right + 1;
}
}

View File

@ -1,65 +0,0 @@
package com.code.lint.y2020.m01.d27;
import entiy.TreeNode;
import util.CreateTree;
import java.util.ArrayList;
import java.util.List;
/**
* error
* @Author: hyy
* @Date: 2020-01-27 15:48
*/
public class PreorderTraversal {
/**
* @param root: A Tree
* @return: Preorder in ArrayList which contains node values.
*/
// public static List<Integer> preorderTraversal(TreeNode root) {
// // write your code here
// List<TreeNode> treeNodes = new ArrayList<>();
// List<Integer> trees = new ArrayList<>();
// if(root==null){
// return new ArrayList<>();
// }
// while (root!=null||treeNodes.size()>0){
// while(root!=null){
// trees.add(root.val);
// treeNodes.add(root);
// root = root.left;
// }
// if(treeNodes.size()>0){
// root = treeNodes.get(treeNodes.size()-1).right;
// treeNodes.remove(treeNodes.size()-1);
// }
// }
// return trees;
// }
static List<Integer> tree = new ArrayList<>();
public static List<Integer> preorderTraversal(TreeNode root) {
// write your code here
if(root==null){
return new ArrayList<>();
}
tree.add(root.val);
if(root.left!=null){
preorderTraversal(root.left);
}
if(root.right!=null){
preorderTraversal(root.right);
}
return tree;
}
public static void main(String[] args) {
// TreeNode treeNode3 = new TreeNode(3);
// TreeNode treeNode2 = new TreeNode(2);
// TreeNode treeNode1 = new TreeNode(1);
// treeNode1.left = treeNode2;
// treeNode1.right = treeNode3;
TreeNode root = CreateTree.createTree("1,#,2,3");
preorderTraversal(root);
}
}

View File

@ -1,134 +0,0 @@
package com.code.lint.y2020.m01.d28;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 57. 三数之和
*
* 给出一个有n个整数的数组S在S中找到三个整数a, b, c找到所有使得a + b + c = 0的三元组
*
* @Author: hyy
* @Date: 2020-01-28 15:16
*/
public class ThreeSum {
/**
* @param numbers: Give an array numbers of n integer
* @return: Find all unique triplets in the array which gives the sum of zero.
*/
// static List<List<Integer>> result = new ArrayList<>();
// static LinkedList<Integer> sum = new LinkedList<>();
// public static List<List<Integer>> threeSum(int[] numbers) {
// // write your code here
// List<Integer> date = new ArrayList<>();
// for (int i=0;i<numbers.length;i++){
// for(int j=i+1;j<numbers.length;j++){
// if(numbers[i]>numbers[j]){
// int temp = numbers[i];
// numbers[i] = numbers[j];
// numbers[j] = temp;
// }
// }
// date.add(numbers[i]);
// }
// for (int i=2;i<date.size();i++){
// if(date.get(i).equals(date.get(i-2))){
// date.remove(i);
// }
// }
// getData(date,sum,3);
// for (int i=result.size()-1;i>=0;i--){
// List<Integer> nums = result.get(i);
// int sum = 0;
// for(int num:nums){
// sum += num;
// }
// if(sum!=0){
// result.remove(nums);
// }
// }
// for (int i=0;i<result.size();i++){
// for(int j=result.size()-1;j>i;j--){
// if(result.get(j).get(0).equals(result.get(i).get(0))&&result.get(j).get(1).equals(result.get(i).get(1))){
// result.remove(j);
// }
// }
// date.add(numbers[i]);
// }
// if(result.size()==1&&result.get(0).size()==0){
// result = null;
// }
// return result;
// }
// public static void getData(List<Integer> date, LinkedList<Integer> sum, int length){
// if(length==0){
// result.add((List<Integer>)sum.clone());
// return;
// }
// for (int i=0;i<date.size();i++){
// sum.addLast(date.get(i));
// List<Integer> newDate = new ArrayList<>(date);
// for (int j=i;j>=0;j--){
// newDate.remove(j);
// }
// getData(newDate,sum,length-1);
// sum.removeLast();
// }
// }
public static List<List<Integer>> threeSum(int[] numbers) {
List<List<Integer>> result = new ArrayList<>();
if (numbers == null || numbers.length < 3) {
return result;
}
Arrays.sort(numbers);
for (int i = 0; i < numbers.length - 2; i++) {
if (i > 0 && numbers[i] == numbers[i - 1]) {
continue;
}
int left = i + 1;
int right = numbers.length - 1;
int target = numbers[i];
sum(numbers, left, right, target, result);
}
return result;
}
public static void sum(int[] numbers, int left, int right, int target, List<List<Integer>> result) {
int oldLeft = 0;
int status = 1;
while (left < right) {
if (numbers[left] + numbers[right] + target == 0) {
List<Integer> list = new ArrayList<>();
if (status == 1) {
list.add(target);
list.add(numbers[left]);
list.add(numbers[right]);
result.add(list);
oldLeft = numbers[left];
status = 0;
} else if (oldLeft != numbers[left]) {
list.add(target);
list.add(numbers[left]);
list.add(numbers[right]);
result.add(list);
oldLeft = numbers[left];
}
left++;
right--;
status = 0;
} else if (numbers[left] + numbers[right] + target < 0) {
left++;
} else {
right--;
}
}
}
public static void main(String[] args) {
int[] nums = new int[]{0, 0, 0, 0, 92, 0, -3002, 0, 0, 0, -10, -19, 0, 65, 0, 0, 293, 0, 1, 1, 1, 9, 9, 9, 10, 11, 1001, 2001, -404, 201, 203, 201, 999, 345, 1, 1, 1, 1, 1, 1, 1, -2, 1, 1, 1, 1, 1, 1, 1, 1, -2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1200, 1, 1, 1, 1, 1, 2, 1202, 2, 2, -4, 2, 2, 2, 2, 4, 5, 6, 1, 1, -11, 1, 1, 1, 1, 1, 1, 1, 1, 101, 1, 1, 1, 1, 1, -1, 1, -6};
threeSum(nums);
}
}

View File

@ -1,92 +0,0 @@
package com.code.lint.y2020.m02.d10;
/**
* @Author: hyy
* @Date: 2020-02-10 23:42
*/
public class KthLargestElement {
/**
* @param n: An integer
* @param nums: An array
* @return: the Kth largest element
*/
// public static int kthLargestElement(int n, int[] nums) {
// // write your code here
// if(nums==null||nums.length==0){
// return -1;
// }
// return quickSort(nums,0,nums.length-1,n);
// }
//
// public int quickSort(int[] nums,int start,int end,int k){
// if(start==end){
// return nums[k];
// }
// int left = start;
// int right=end;
// int point=nums[(start+end)/2];
// while (left<=right){
// while (left<=right&&nums[left]<point){
// left++;
// }
// while (left<=right&&nums[right]>point){
// left--;
// }
// if(left<=right){
// int temp=nums[left];
// nums[left]=nums[right];
// nums[right]=temp;
// left++;
// right--;
// }
// }
// if(k<=right){
// return quickSort(nums,start,right,k);
// }
// if(start+k-1>=left){
// return quickSort(nums,left,end,k);
// }
// return nums[k];
// }
public int kthLargestElement(int n, int[] nums) {
int begin = 0, end = nums.length - 1;
int pos = 0;
while (begin <= end) {
pos = partion(nums, begin, end);
if (pos == n - 1) {
return nums[pos];
} else if (pos > n - 1) {
end = pos - 1;
} else {
begin = pos + 1;
}
}
return -1;
}
private static int partion(int[] data, int begin, int end) {
int temp = data[begin];
while (begin < end) {
while (begin < end && data[end] <= temp) {
end--;
}
swap(data, begin, end);
while (begin < end && data[begin] > temp) {
begin++;
}
swap(data, begin, end);
}
return begin;
}
public static void swap(int[] arr, int i, int j) {
if (arr == null || i >= arr.length || j >= arr.length || i < 0 || j < 0) {
return;
}
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}

View File

@ -1,59 +0,0 @@
package com.code.lint.y2020.m02.d10;
/**
* @Author: hyy
* @Date: 2020-02-10 21:05
*/
public class KthSmallestElement {
/**
* @param k: An integer
* @param nums: An array
* @return: the Kth largest element
*/
public static int kthSmallest(int k, int[] nums) {
int begin = 0, end = nums.length - 1;
int pos = 0;
while (begin <= end) {
pos = partion(nums, begin, end);
if (pos == k - 1) {
return nums[pos];
} else if (pos > k - 1) {
end = pos - 1;
} else {
begin = pos + 1;
}
}
return -1;
}
private static int partion(int[] data, int begin, int end) {
int temp = data[begin];
while (begin < end) {
while (begin < end && data[end] >= temp) {
end--;
}
swap(data, begin, end);
while (begin < end && data[begin] < temp) {
begin++;
}
swap(data, begin, end);
}
return begin;
}
public static void swap(int[] arr, int i, int j) {
if (arr == null || i >= arr.length || j >= arr.length || i < 0 || j < 0) {
return;
}
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void main(String[] args) {
int[] nums = new int[]{9, 3, 2, 4, 8};
System.out.println(kthSmallest(1, nums));
}
}

View File

@ -1,37 +0,0 @@
package com.code.lint.y2020.m02.d10;
/**
* @Author: hyy
* @Date: 2020-02-10 20:35
*/
public class PartitionArray {
/**
* @param nums: The integer array you should partition
* @param k: An integer
* @return: The index after partition
*/
public static int partitionArray(int[] nums, int k) {
// write your code here
int max = nums.length;
if (max > 0) {
for (int i = 0; i < max; i++) {
while (nums[i] >= k) {
int temp = nums[i];
nums[i] = nums[max - 1];
nums[max - 1] = temp;
max--;
if(i==max){
break;
}
}
}
}
return max;
}
public static void main(String[] args) {
int[] nums = new int[]{3,2,1};
System.out.println(partitionArray(nums,2));
}
}

View File

@ -1,27 +0,0 @@
package com.code.lint.y2020.m02.d10;
/**
* 整数排序 II
* @Author: hyy
* @Date: 2020-02-10 20:11
*/
public class SortColors2 {
/**
* @param colors: A list of integer
* @param k: An integer
* @return: nothing
*/
public void sortColors2(int[] colors, int k) {
// write your code here
for (int i = 0; i < colors.length; i++) {
for (int j = i + 1; j < colors.length; j++) {
if (colors[i] > colors[j]) {
int temp = colors[i];
colors[i] = colors[j];
colors[j] = temp;
}
}
}
}
}

View File

@ -1,46 +0,0 @@
package com.code.lint.y2020.m02.d10;
/**
* @Author: hyy
* @Date: 2020-02-10 20:18
*/
public class SortIntegers2 {
/**
* @param A: an integer array
* @return: nothing
*/
public static void sortIntegers2(int[] A) {
// write your code here
quickSort(A,0,A.length-1);
}
public static void quickSort(int[] nums,int start,int end){
if(start<end){
int index = getIndex(nums,start,end);
quickSort(nums,start,index-1);
quickSort(nums,index+1,end);
}
}
public static int getIndex(int[] nums,int start,int end){
int temp = nums[start];
while (start<end){
while (start<end&&nums[end]>=temp){
end--;
}
nums[start]=nums[end];
while(start<end&&nums[start]<=temp){
start++;
}
nums[end]=nums[start];
}
nums[start]=temp;
return start;
}
public static void main(String[] args) {
int[] nums = new int[]{3,2,1,4,5};
sortIntegers2(nums);
}
}

View File

@ -1,50 +0,0 @@
package com.code.lint.y2020.m02.d11;
import java.util.Arrays;
/**
* @Author: hyy
* @Date: 2020-02-11 17:21
*/
public class DoingHomework {
/**
* @param cost: the cost
* @param val: the val
* @return: the all cost
*/
public static long doingHomework(int[] cost, int[] val) {
// Write your code here.
long sums = 0;
long sum = 0;
int index = 0;
Arrays.sort(val);
for (int i = 0; i < val.length; i++) {
val[i] -= sum;
if (val[i] < cost[index]) {
continue;
}
int j = 0;
for (j = index; j < cost.length; j++) {
if (val[i] >= cost[j]) {
sums += cost[j] * (val.length - i);
sum += cost[j];
val[i] -= cost[j];
} else {
index = j;
break;
}
}
if (j == cost.length) {
break;
}
}
return sums;
}
public static void main(String[] args) {
int[] cost = new int[]{3, 3, 3};
int[] val = new int[]{7, 15, 11, 13, 1, 6, 11, 15, 11, 1, 8, 9, 13, 9, 1};
System.out.println(doingHomework(cost, val));
}
}

View File

@ -1,42 +0,0 @@
package com.code.lint.y2020.m02.d11;
/**
* @Author: hyy
* @Date: 2020-02-11 09:40
*/
import entiy.SVNRepo;
/**
* public class SVNRepo {
* public static boolean isBadVersion(int k);
* }
* you can use SVNRepo.isBadVersion(k) to judge whether
* the kth code version is bad or not.
*/
public class FindFirstBadVersion {
/**
* @param n: An integer
* @return: An integer which is the first bad version.
*/
public int findFirstBadVersion(int n) {
// write your code here
int start = 1;
int end = n;
int index = (start + end) / 2;
while (start < index && index < end) {
if (SVNRepo.isBadVersion(index) == true) {
end = index;
} else {
start = index;
}
index = (start + end) / 2;
}
if (SVNRepo.isBadVersion(start) == true) {
index = start;
} else {
index = end;
}
return index;
}
}

View File

@ -1,23 +0,0 @@
package com.code.lint.y2020.m02.d11;
/**
* @Author: hyy
* @Date: 2020-02-11 11:16
*/
public class FindMin {
/**
* @param nums: a rotated sorted array
* @return: the minimum number in the array
*/
public int findMin(int[] nums) {
// write your code here
int min = nums[0];
for (int i = 1; i < nums.length; i++) {
if (nums[i] < min) {
min = nums[i];
}
}
return min;
}
}

View File

@ -1,49 +0,0 @@
package com.code.lint.y2020.m02.d11;
/**
* 75. 寻找峰值
*
* 你给出一个整数数组(size为n)其具有以下特点
*
* 相邻位置的数字是不同的
* A[0] < A[1] 并且 A[n - 2] > A[n - 1]
*
* 假定P是峰值的位置则满足A[P] > A[P-1]且A[P] > A[P+1]返回数组中任意一个峰值的位置
*
* @Author: hyy
* @Date: 2020-02-11 11:25
*/
public class FindPeak {
/**
* @param A: An integers array.
* @return: return any of peek positions.
*/
public static int findPeak(int[] A) {
// write your code here
int start = 1;
int end = A.length - 2;
int index = (start + end) / 2;
while (start < index && index < end) {
if (index > 0 && A[index - 1] < A[index] && A[index] > A[index + 1]) {
break;
} else if (A[index - 1] > A[index]) {
end = index - 1;
} else {
start = index + 1;
}
index = (start + end) / 2;
}
if (A[start] > A[start - 1] && A[start] > A[start + 1]) {
index = start;
} else if (A[end] > A[end +-1] && A[end] > A[end + 1]) {
index = end;
}
return index;
}
public static void main(String[] args) {
int[] nums = new int[]{100,102,104,7,9,11,4,3};
System.out.println(findPeak(nums));
}
}

View File

@ -1,53 +0,0 @@
package com.code.lint.y2020.m02.d11;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @Author: hyy
* @Date: 2020-02-11 14:58
*/
public class GetDistance {
/**
* @param n: The total number of stones.
* @param m: The total number of stones you can remove.
* @param target: The distance from the end to the starting point.
* @param nums: The array that the distance from the i rock to the starting point is nums[i].
* @return: Return the maximum value of the shortest jump distance.
*/
public static int getDistance(int n, int m, int target, List<Integer> d) {
// Write your code here.
List<Integer> nums = new ArrayList<>(d);
nums.add(target);
int start = 0;
int end = target;
while (start <= end) {
int index = (start + end) / 2;
int count = 0;
for (int i = 0, x = 0; i <= n; ) {
i++;
if (nums.get(i) - nums.get(x) < index) {
count++;
} else {
x = i;
}
}
if (count <= m) {
start = index + 1;
} else {
end = index - 1;
}
}
return start - 1;
}
public static void main(String[] args) {
int n = 100;
int m = 40;
int target = 53428902;
List<Integer> d = Arrays.asList(137872, 312786, 640276, 718243, 995859, 1188568, 1229359, 1549474, 1843642, 1931010, 2242465, 2430010, 2549796, 2902294, 3396266, 3521509, 3961579, 4297275, 4613587, 4614842, 5074008, 5094591, 5327198, 5860009, 5945922, 6341191, 6655012, 6816932, 7084191, 7109821, 7640178, 7936610, 8026301, 8054873, 8545942, 8989726, 9224735, 9244360, 9331817, 9406546, 9898145, 10239978, 10764311, 10962958, 10972250, 11128108, 11319843, 11515655, 11818594, 12283648, 12403800, 12631814, 12885894, 13202229, 13229659, 13362406, 13446983, 13639755, 13783223, 14210368, 14292516, 14787853, 14808906, 15269292, 15393700, 15607344, 15858474, 16279493, 16281697, 16551566, 16646986, 17129598, 17270469, 17599294, 18119162, 18371807, 18492487, 18611563, 18843930, 18927526, 19164215, 19465972, 19637549, 19973483, 20262894, 20600381, 20736572, 21174736, 21475457, 21824861, 21986321, 22213204, 22705607, 22708998, 23140278, 23212977, 23378634, 23677390, 23708887, 23728739);
System.out.println(getDistance(n, m, target, d));
}
}

View File

@ -1,43 +0,0 @@
package com.code.lint.y2020.m02.d11;
/**
* @Author: hyy
* @Date: 2020-02-11 02:33
*/
public class IntervalStatistics {
/**
* @param arr: the 01 array
* @param k: the limit
* @return: the sum of the interval
*/
public static long intervalStatistics(int[] arr, int k) {
// Write your code here.
long count = 0;
for (int i = 0; i < arr.length; i++) {
if(arr[i]!=0){
continue;
}
int num = 0;
for (int j = i; j < arr.length; j++) {
if(arr[j]!=0){
if (arr[j] == 1) {
num++;
}
continue;
}
if (num <= k) {
count++;
} else {
break;
}
}
}
return count;
}
public static void main(String[] args) {
int[] nums = new int[]{0, 0, 1, 0, 1, 1, 0};
System.out.println(intervalStatistics(nums, 1));
}
}

View File

@ -1,40 +0,0 @@
package com.code.lint.y2020.m02.d11;
import java.util.Arrays;
/**
* @Author: hyy
* @Date: 2020-02-11 23:36
*/
/**
* 945 任务计划
*/
public class LeastInterval {
/**
* @param tasks: the given char array representing tasks CPU need to do
* @param n: the non-negative cooling interval
* @return: the least number of intervals the CPU will take to finish all the given tasks
*/
public static int leastInterval(char[] tasks, int n) {
// write your code here
int[] ch = new int[26];
for(char c : tasks){
ch[c-'A']++;
}
Arrays.sort(ch);
int i = 25;
while (i>=0 && ch[i]==ch[25]){
i--;
}
return Math.max(tasks.length, (ch[25] - 1) * (n + 1) + 25 - i);
}
public static void main(String[] args) {
String str = "BFJJCHICEGCEJFGJBIBBCBGAJHCGDEHEHAHIAJCGBGHGH";
char[] tasks = str.toCharArray();
// char[] tasks = new char[]{'A', 'A', 'A', 'B', 'B', 'B'};
int n = 15;
System.out.println(leastInterval(tasks, n));
}
}

View File

@ -1,43 +0,0 @@
package com.code.lint.y2020.m02.d11;
/**
* @Author: hyy
* @Date: 2020-02-11 22:06
*/
public class LengthOfLongestSubstring {
/**
* @param s: a string
* @return: an integer
*/
public static int lengthOfLongestSubstring(String s) {
// write your code here
if (s.length() < 2) {
return s.length();
}
int count = 1;
int num = 1;
int start = 0;
for (int i = 1; i < s.length(); i++) {
int index = s.substring(start, i).indexOf(s.substring(i, i + 1));
if (index == -1) {
num++;
} else {
if (num > count) {
count = num;
}
start += index + 1;
num = num - index;
}
}
if (num > count) {
count = num;
}
return count;
}
public static void main(String[] args) {
String str = "bpfbhmipx";
System.out.println(lengthOfLongestSubstring(str));
}
}

View File

@ -1,73 +0,0 @@
package com.code.lint.y2020.m02.d11;
import java.util.Stack;
/**
* 12. 带最小值操作的栈
*
* 实现一个栈, 支持以下操作:
*
* push(val) val 压入栈
* pop() 将栈顶元素弹出, 并返回这个弹出的元素
* min() 返回栈中元素的最小值
*
* 要求 O(1) 开销.
*
* @Author: hyy
* @Date: 2020-02-11 21:46
*/
public class MinStack {
public MinStack() {
// do intialization if necessary
}
Stack<Integer> stack = new Stack<Integer>();
Stack<Integer> minstack = new Stack<Integer>();
/**
* @param number: An integer
* @return: nothing
*/
public void push(int number) {
// write your code here
stack.push(number);
int top;
if (!minstack.empty()) {
top = minstack.peek();
} else {
top = number;
}
if (number < top) {
minstack.push(number);
} else {
minstack.push(top);
}
}
/**
* @return: An integer
*/
public int pop() {
// write your code here
int data = 0;
if(!stack.empty()){
data = stack.peek();
stack.pop();
minstack.pop();
}
return data;
}
/**
* @return: An integer
*/
public int min() {
// write your code here
int data = 0;
if(!minstack.empty()){
data = minstack.peek();
}
return data;
}
}

Some files were not shown because too many files have changed in this diff Show More