外观数列
题目链接:外观数列
个人版本一(遍历)
class Solution {
public String countAndSay(int n) {
String str = "11", tempStr;
if(n == 1){
return "1";
}
if(n == 2){
return "11";
}
int i, j, count, len;
for( i=2 ; i<n ; i++){
tempStr = "";
len = str.length();
j = 1;
while (j<=len){
count = 1;
while (j < len && str.charAt(j) == str.charAt(j-1)){
count++;
j++;
}
tempStr += count+""+str.charAt(j-1);
j++;
}
str = tempStr;
}
return str;
}
}
官方版本一(遍历)
class Solution {
public String countAndSay(int n) {
String str = "1";
for (int i = 2; i <= n; ++i) {
StringBuilder sb = new StringBuilder();
int start = 0;
int pos = 0;
while (pos < str.length()) {
while (pos < str.length() && str.charAt(pos) == str.charAt(start)) {
pos++;
}
sb.append(Integer.toString(pos - start)).append(str.charAt(start));
start = pos;
}
str = sb.toString();
}
return str;
}
}
官方版本二(暴力打表)
class Solution {
public String countAndSay(int n) {
String[] arr = {
"","1","11","21","1211","111221","312211","13112221","1113213211","31131211131221","13211311123113112211","11131221133112132113212221","3113112221232112111312211312113211","1321132132111213122112311311222113111221131221","11131221131211131231121113112221121321132132211331222113112211","311311222113111231131112132112311321322112111312211312111322212311322113212221","132113213221133112132113311211131221121321131211132221123113112221131112311332111213211322211312113211","11131221131211132221232112111312212321123113112221121113122113111231133221121321132132211331121321231231121113122113322113111221131221","31131122211311123113321112131221123113112211121312211213211321322112311311222113311213212322211211131221131211132221232112111312111213111213211231131122212322211331222113112211","1321132132211331121321231231121113112221121321132122311211131122211211131221131211132221121321132132212321121113121112133221123113112221131112311332111213122112311311123112111331121113122112132113213211121332212311322113212221","11131221131211132221232112111312111213111213211231132132211211131221131211221321123113213221123113112221131112311332211211131221131211132211121312211231131112311211232221121321132132211331121321231231121113112221121321133112132112312321123113112221121113122113121113123112112322111213211322211312113211","311311222113111231133211121312211231131112311211133112111312211213211312111322211231131122211311122122111312211213211312111322211213211321322113311213212322211231131122211311123113223112111311222112132113311213211221121332211211131221131211132221232112111312111213111213211231132132211211131221232112111312211213111213122112132113213221123113112221131112311311121321122112132231121113122113322113111221131221","132113213221133112132123123112111311222112132113311213211231232112311311222112111312211311123113322112132113213221133122112231131122211211131221131112311332211211131221131211132221232112111312111213322112132113213221133112132113221321123113213221121113122123211211131221222112112322211231131122211311123113321112131221123113111231121113311211131221121321131211132221123113112211121312211231131122211211133112111311222112111312211312111322211213211321322113311213211331121113122122211211132213211231131122212322211331222113112211","111312211312111322212321121113121112131112132112311321322112111312212321121113122112131112131221121321132132211231131122211331121321232221121113122113121113222123112221221321132132211231131122211331121321232221123113112221131112311332111213122112311311123112112322211211131221131211132221232112111312211322111312211213211312111322211231131122111213122112311311221132211221121332211213211321322113311213212312311211131122211213211331121321123123211231131122211211131221131112311332211213211321223112111311222112132113213221123123211231132132211231131122211311123113322112111312211312111322212321121113122123211231131122113221123113221113122112132113213211121332212311322113212221","3113112221131112311332111213122112311311123112111331121113122112132113121113222112311311221112131221123113112221121113311211131122211211131221131211132221121321132132212321121113121112133221123113112221131112311332111213213211221113122113121113222112132113213221232112111312111213322112132113213221133112132123123112111311222112132113311213211221121332211231131122211311123113321112131221123113112221132231131122211211131221131112311332211213211321223112111311222112132113212221132221222112112322211211131221131211132221232112111312111213111213211231132132211211131221232112111312211213111213122112132113213221123113112221133112132123222112111312211312112213211231132132211211131221131211132221121311121312211213211312111322211213211321322113311213212322211231131122211311123113321112131221123113112211121312211213211321222113222112132113223113112221121113122113121113123112112322111213211322211312113211","132113213221133112132123123112111311222112132113311213211231232112311311222112111312211311123113322112132113212231121113112221121321132132211231232112311321322112311311222113111231133221121113122113121113221112131221123113111231121123222112132113213221133112132123123112111312111312212231131122211311123113322112111312211312111322111213122112311311123112112322211211131221131211132221232112111312111213111213211231132132211211131221232112111312212221121123222112132113213221133112132123123112111311222112132113213221132213211321322112311311222113311213212322211211131221131211221321123113213221121113122113121132211332113221122112133221123113112221131112311332111213122112311311123112111331121113122112132113121113222112311311221112131221123113112221121113311211131122211211131221131211132221121321132132212321121113121112133221123113112221131112212211131221121321131211132221123113112221131112311332211211133112111311222112111312211311123113322112111312211312111322212321121113121112133221121321132132211331121321231231121113112221121321132122311211131122211211131221131211322113322112111312211322132113213221123113112221131112311311121321122112132231121113122113322113111221131221","1113122113121113222123211211131211121311121321123113213221121113122123211211131221121311121312211213211321322112311311222113311213212322211211131221131211221321123113213221121113122113121113222112131112131221121321131211132221121321132132211331121321232221123113112221131112311322311211131122211213211331121321122112133221121113122113121113222123211211131211121311121321123113111231131122112213211321322113311213212322211231131122211311123113223112111311222112132113311213211221121332211231131122211311123113321112131221123113111231121113311211131221121321131211132221123113112211121312211231131122113221122112133221121113122113121113222123211211131211121311121321123113213221121113122113121113222113221113122113121113222112132113213221232112111312111213322112311311222113111221221113122112132113121113222112311311222113111221132221231221132221222112112322211213211321322113311213212312311211131122211213211331121321123123211231131122211211131221131112311332211213211321223112111311222112132113213221123123211231132132211231131122211311123113322112111312211312111322111213122112311311123112112322211213211321322113312211223113112221121113122113111231133221121321132132211331121321232221123123211231132132211231131122211331121321232221123113112221131112311332111213122112311311123112112322211211131221131211132221232112111312111213111213211231132132211211131221131211221321123113213221123113112221131112211322212322211231131122211322111312211312111322211213211321322113311213211331121113122122211211132213211231131122212322211331222113112211","31131122211311123113321112131221123113111231121113311211131221121321131211132221123113112211121312211231131122211211133112111311222112111312211312111322211213211321322123211211131211121332211231131122211311122122111312211213211312111322211231131122211311123113322112111331121113112221121113122113111231133221121113122113121113222123211211131211121332211213211321322113311213211322132112311321322112111312212321121113122122211211232221123113112221131112311332111213122112311311123112111331121113122112132113311213211321222122111312211312111322212321121113121112133221121321132132211331121321132213211231132132211211131221232112111312212221121123222112132113213221133112132123123112111311222112132113311213211231232112311311222112111312211311123113322112132113212231121113112221121321132122211322212221121123222112311311222113111231133211121312211231131112311211133112111312211213211312111322211231131122211311123113322113223113112221131112311332211211131221131211132211121312211231131112311211232221121321132132211331221122311311222112111312211311123113322112132113213221133122211332111213112221133211322112211213322112111312211312111322212321121113121112131112132112311321322112111312212321121113122112131112131221121321132132211231131122211331121321232221121113122113121122132112311321322112111312211312111322211213111213122112132113121113222112132113213221133112132123222112311311222113111231132231121113112221121321133112132112211213322112111312211312111322212311222122132113213221123113112221133112132123222112111312211312111322212321121113121112133221121311121312211213211312111322211213211321322123211211131211121332211213211321322113311213212312311211131122211213211331121321122112133221123113112221131112311332111213122112311311123112111331121113122112132113121113222112311311222113111221221113122112132113121113222112132113213221133122211332111213322112132113213221132231131122211311123113322112111312211312111322212321121113122123211231131122113221123113221113122112132113213211121332212311322113212221","13211321322113311213212312311211131122211213211331121321123123211231131122211211131221131112311332211213211321223112111311222112132113213221123123211231132132211231131122211311123113322112111312211312111322111213122112311311123112112322211213211321322113312211223113112221121113122113111231133221121321132132211331121321232221123123211231132132211231131122211331121321232221123113112221131112311332111213122112311311123112112322211211131221131211132221232112111312211322111312211213211312111322211231131122111213122112311311221132211221121332211213211321322113311213212312311211131122211213211331121321123123211231131122211211131221232112111312211312113211223113112221131112311332111213122112311311123112112322211211131221131211132221232112111312211322111312211213211312111322211231131122111213122112311311221132211221121332211211131221131211132221232112111312111213111213211231132132211211131221232112111312211213111213122112132113213221123113112221133112132123222112111312211312112213211231132132211211131221131211322113321132211221121332211213211321322113311213212312311211131122211213211331121321123123211231131122211211131221131112311332211213211321322113311213212322211322132113213221133112132123222112311311222113111231132231121113112221121321133112132112211213322112111312211312111322212311222122132113213221123113112221133112132123222112111312211312111322212311322123123112111321322123122113222122211211232221123113112221131112311332111213122112311311123112111331121113122112132113121113222112311311221112131221123113112221121113311211131122211211131221131211132221121321132132212321121113121112133221123113112221131112212211131221121321131211132221123113112221131112311332211211133112111311222112111312211311123113322112111312211312111322212321121113121112133221121321132132211331121321132213211231132132211211131221232112111312212221121123222112311311222113111231133211121321321122111312211312111322211213211321322123211211131211121332211231131122211311123113321112131221123113111231121123222112111331121113112221121113122113111231133221121113122113121113221112131221123113111231121123222112111312211312111322212321121113121112131112132112311321322112111312212321121113122122211211232221121321132132211331121321231231121113112221121321133112132112312321123113112221121113122113111231133221121321132132211331221122311311222112111312211311123113322112111312211312111322212311322123123112112322211211131221131211132221132213211321322113311213212322211231131122211311123113321112131221123113112211121312211213211321222113222112132113223113112221121113122113121113123112112322111213211322211312113211","11131221131211132221232112111312111213111213211231132132211211131221232112111312211213111213122112132113213221123113112221133112132123222112111312211312112213211231132132211211131221131211132221121311121312211213211312111322211213211321322113311213212322211231131122211311123113223112111311222112132113311213211221121332211211131221131211132221231122212213211321322112311311222113311213212322211211131221131211132221232112111312111213322112131112131221121321131211132221121321132132212321121113121112133221121321132132211331121321231231121113112221121321133112132112211213322112311311222113111231133211121312211231131122211322311311222112111312211311123113322112132113212231121113112221121321132122211322212221121123222112111312211312111322212321121113121112131112132112311321322112111312212321121113122112131112131221121321132132211231131122111213122112311311222113111221131221221321132132211331121321231231121113112221121321133112132112211213322112311311222113111231133211121312211231131122211322311311222112111312211311123113322112132113212231121113112221121321132122211322212221121123222112311311222113111231133211121312211231131112311211133112111312211213211312111322211231131122111213122112311311222112111331121113112221121113122113121113222112132113213221232112111312111213322112311311222113111221221113122112132113121113222112311311222113111221132221231221132221222112112322211211131221131211132221232112111312111213111213211231132132211211131221232112111312211213111213122112132113213221123113112221133112132123222112111312211312111322212321121113121112133221132211131221131211132221232112111312111213322112132113213221133112132113221321123113213221121113122123211211131221222112112322211231131122211311123113321112132132112211131221131211132221121321132132212321121113121112133221123113112221131112311332111213211322111213111213211231131211132211121311222113321132211221121332211213211321322113311213212312311211131122211213211331121321123123211231131122211211131221131112311332211213211321223112111311222112132113213221123123211231132132211231131122211311123113322112111312211312111322111213122112311311123112112322211213211321322113312211223113112221121113122113111231133221121321132132211331121321232221123123211231132132211231131122211331121321232221123113112221131112311332111213122112311311123112112322211211131221131211132221232112111312211322111312211213211312111322211231131122111213122112311311221132211221121332211213211321322113311213212312311211131211131221223113112221131112311332211211131221131211132211121312211231131112311211232221121321132132211331121321231231121113112221121321133112132112211213322112312321123113213221123113112221133112132123222112311311222113111231132231121113112221121321133112132112211213322112311311222113111231133211121312211231131112311211133112111312211213211312111322211231131122111213122112311311221132211221121332211211131221131211132221232112111312111213111213211231132132211211131221232112111312211213111213122112132113213221123113112221133112132123222112111312211312111322212311222122132113213221123113112221133112132123222112311311222113111231133211121321132211121311121321122112133221123113112221131112311332211322111312211312111322212321121113121112133221121321132132211331121321231231121113112221121321132122311211131122211211131221131211322113322112111312211322132113213221123113112221131112311311121321122112132231121113122113322113111221131221","3113112221131112311332111213122112311311123112111331121113122112132113121113222112311311221112131221123113112221121113311211131122211211131221131211132221121321132132212321121113121112133221123113112221131112212211131221121321131211132221123113112221131112311332211211133112111311222112111312211311123113322112111312211312111322212321121113121112133221121321132132211331121321132213211231132132211211131221232112111312212221121123222112311311222113111231133211121321321122111312211312111322211213211321322123211211131211121332211231131122211311123113321112131221123113111231121123222112111331121113112221121113122113111231133221121113122113121113221112131221123113111231121123222112111312211312111322212321121113121112131112132112311321322112111312212321121113122122211211232221121321132132211331121321231231121113112221121321132132211322132113213221123113112221133112132123222112111312211312112213211231132132211211131221131211322113321132211221121332211231131122211311123113321112131221123113111231121113311211131221121321131211132221123113112211121312211231131122211211133112111311222112111312211312111322211213211321223112111311222112132113213221133122211311221122111312211312111322212321121113121112131112132112311321322112111312212321121113122122211211232221121321132132211331121321231231121113112221121321132132211322132113213221123113112221133112132123222112111312211312112213211231132132211211131221131211322113321132211221121332211213211321322113311213212312311211131122211213211331121321123123211231131122211211131221131112311332211213211321223112111311222112132113213221123123211231132132211231131122211311123113322112111312211312111322111213122112311311123112112322211213211321322113312211223113112221121113122113111231133221121321132132211331222113321112131122211332113221122112133221123113112221131112311332111213122112311311123112111331121113122112132113121113222112311311221112131221123113112221121113311211131122211211131221131211132221121321132132212321121113121112133221123113112221131112311332111213122112311311123112112322211322311311222113111231133211121312211231131112311211232221121113122113121113222123211211131221132211131221121321131211132221123113112211121312211231131122113221122112133221121321132132211331121321231231121113121113122122311311222113111231133221121113122113121113221112131221123113111231121123222112132113213221133112132123123112111312211322311211133112111312211213211311123113223112111321322123122113222122211211232221121113122113121113222123211211131211121311121321123113213221121113122123211211131221121311121312211213211321322112311311222113311213212322211211131221131211221321123113213221121113122113121113222112131112131221121321131211132221121321132132211331121321232221123113112221131112311322311211131122211213211331121321122112133221121113122113121113222123112221221321132132211231131122211331121321232221121113122113121113222123211211131211121332211213111213122112132113121113222112132113213221232112111312111213322112132113213221133112132123123112111311222112132113311213211221121332211231131122211311123113321112131221123113112221132231131122211211131221131112311332211213211321223112111311222112132113212221132221222112112322211211131221131211132221232112111312111213111213211231131112311311221122132113213221133112132123222112311311222113111231132231121113112221121321133112132112211213322112111312211312111322212321121113121112131112132112311321322112111312212321121113122122211211232221121311121312211213211312111322211213211321322123211211131211121332211213211321322113311213211322132112311321322112111312212321121113122122211211232221121321132132211331121321231231121113112221121321133112132112312321123113112221121113122113111231133221121321132122311211131122211213211321222113222122211211232221123113112221131112311332111213122112311311123112111331121113122112132113121113222112311311221112131221123113112221121113311211131122211211131221131211132221121321132132212321121113121112133221123113112221131112311332111213213211221113122113121113222112132113213221232112111312111213322112132113213221133112132123123112111312211322311211133112111312212221121123222112132113213221133112132123222113223113112221131112311332111213122112311311123112112322211211131221131211132221232112111312111213111213211231132132211211131221131211221321123113213221123113112221131112211322212322211231131122211322111312211312111322211213211321322113311213211331121113122122211211132213211231131122212322211331222113112211"
};
return arr[n];
}
}
组合总和
题目链接:组合总和
个人版本一
class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
Arrays.sort(candidates);
List<List<Integer>> list = new ArrayList<>();
getSum(list, candidates, candidates.length-1, 0, target, new Stack<Integer>());
return list;
}
public void getSum(List<List<Integer>> list, int[] candidates, int pos, int sum, int target, Stack<Integer> stack){
while (pos >= 0){
int now = candidates[pos];
int all = sum + now;
if(all < target){
stack.push(now);
getSum(list, candidates, pos, sum+now, target, stack);
stack.pop();
}else if(all == target){
List<Integer> l = new ArrayList<>(stack);
l.add(now);
list.add(l);
}
pos--;
}
}
}
官方版本一
class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> ans = new ArrayList<List<Integer>>();
List<Integer> combine = new ArrayList<Integer>();
dfs(candidates, target, ans, combine, 0);
return ans;
}
public void dfs(int[] candidates, int target, List<List<Integer>> ans, List<Integer> combine, int idx) {
if (idx == candidates.length) {
return;
}
if (target == 0) {
ans.add(new ArrayList<Integer>(combine));
return;
}
// 直接跳过
dfs(candidates, target, ans, combine, idx + 1);
// 选择当前数
if (target - candidates[idx] >= 0) {
combine.add(candidates[idx]);
dfs(candidates, target - candidates[idx], ans, combine, idx);
combine.remove(combine.size() - 1);
}
}
}
组合总和 II
题目链接:组合总和 II
个人版本一
class Solution {
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
List<List<Integer>> list = new ArrayList<>();
Arrays.sort(candidates);
getSum(candidates, list, target, new Stack<Integer>(), candidates.length-1, 0);
return list;
}
public void getSum(int[] candidates, List<List<Integer>> list, int target, Stack<Integer> stack, int pos, int sum){
while (pos >= 0){
int all = sum + candidates[pos];
if(all < target){
stack.push(candidates[pos]);
getSum(candidates, list, target, stack, pos-1, all);
stack.pop();
// 去重
while (pos >= 1 && candidates[pos] == candidates[pos-1]){
pos--;
}
}else if(all == target){
List<Integer> l = new ArrayList<>(stack);
l.add(candidates[pos]);
list.add(l);
// 去重
while (pos >= 1 && candidates[pos] == candidates[pos-1]){
pos--;
}
}
pos--;
}
}
}
官方版本一
class Solution {
List<int[]> freq = new ArrayList<int[]>();
List<List<Integer>> ans = new ArrayList<List<Integer>>();
List<Integer> sequence = new ArrayList<Integer>();
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
Arrays.sort(candidates);
for (int num : candidates) {
int size = freq.size();
// 拿到所有数以及他的数量
if (freq.isEmpty() || num != freq.get(size - 1)[0]) {
freq.add(new int[]{num, 1});
} else {
++freq.get(size - 1)[1];
}
}
dfs(0, target);
return ans;
}
// 整个算法逻辑是,先将数组升序,然后一直统计重复,然后在这个不含重复元素的freq列表进行操作,
// 开始是递归到最后的数再往前回溯
// 往前回溯的同时继续往后查找
// 例如1,1,6,7 target=8,开始直接递归到7,往后查找,不符合,就结束
// 往前回溯到6,6往后是7,不符合,然后往前回溯是1,1往后回溯,到6不符合,到7符合了,添加1,7
// 通过freq中的数量去决定添加的次数,因为1的个数是2,添加了2次,所以在添加1,7后,在回溯到1的第二次循环
// 也就添加了1,1,再往后查找,到6就符合了,添加1,1,6
// 这样即避免了重复又达到了要求
public void dfs(int pos, int rest) {
if (rest == 0) {
ans.add(new ArrayList<Integer>(sequence));
return;
}
if (pos == freq.size() || rest < freq.get(pos)[0]) {
return;
}
dfs(pos + 1, rest);
// 用于控制重复
int most = Math.min(rest / freq.get(pos)[0], freq.get(pos)[1]);
for (int i = 1; i <= most; ++i) {
// 遍历操作主要使用来进一步去重处理,例如:1,1,6,7 target=8,
// 不去重就是会有两个1,7
sequence.add(freq.get(pos)[0]);
dfs(pos + 1, rest - i * freq.get(pos)[0]);
}
for (int i = 1; i <= most; ++i) {
sequence.remove(sequence.size() - 1);
}
}
}
其他版本一
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Deque;
import java.util.List;
public class Solution {
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
int len = candidates.length;
List<List<Integer>> res = new ArrayList<>();
if (len == 0) {
return res;
}
// 关键步骤
Arrays.sort(candidates);
Deque<Integer> path = new ArrayDeque<>(len);
dfs(candidates, len, 0, target, path, res);
return res;
}
/**
* @param candidates 候选数组
* @param len 冗余变量
* @param begin 从候选数组的 begin 位置开始搜索
* @param target 表示剩余,这个值一开始等于 target,基于题目中说明的"所有数字(包括目标数)都是正整数"这个条件
* @param path 从根结点到叶子结点的路径
* @param res
*/
private void dfs(int[] candidates, int len, int begin, int target, Deque<Integer> path, List<List<Integer>> res) {
if (target == 0) {
res.add(new ArrayList<>(path));
return;
}
for (int i = begin; i < len; i++) {
// 大剪枝:减去 candidates[i] 小于 0,减去后面的 candidates[i + 1]、candidates[i + 2] 肯定也小于 0,因此用 break
if (target - candidates[i] < 0) {
break;
}
// 小剪枝:同一层相同数值的结点,从第 2 个开始,候选数更少,结果一定发生重复,因此跳过,用 continue
if (i > begin && candidates[i] == candidates[i - 1]) {
continue;
}
path.addLast(candidates[i]);
// 调试语句 ①
// System.out.println("递归之前 => " + path + ",剩余 = " + (target - candidates[i]));
// 因为元素不可以重复使用,这里递归传递下去的是 i + 1 而不是 i
dfs(candidates, len, i + 1, target - candidates[i], path, res);
path.removeLast();
// 调试语句 ②
// System.out.println("递归之后 => " + path + ",剩余 = " + (target - candidates[i]));
}
}
}
接雨水
题目链接:接雨水
个人版本一
class Solution {
// 总思路是找打一个基点,然后往从左往右找到高度等于或大于他的块
// 找到目标块 的同时,统计中间的块数,因为宽度为1,所以高度就是块的总的占用的空间数
// 找到目标块后,计算之间的盛水总数再减去块占用的空间,就是最终的盛水总数
// 因为从左往右不一定存在大于等于该位置的块,所以需要从右往左扫描
// 从右往左扫描结束的位置,是上一次结束的位置,就是找不到存在大于等于他的块的位置
public int trap(int[] height) {
int len = height.length;
if(len < 3) return 0;
int startHeight, i = 0, j, tag = len-1, tempSum = 0, sum = 0;
// 从左到右
while (i < tag){
tempSum = 0; j = i+1;
startHeight = height[i];
// 找到下一个高度大于等于上一个目标块的
while (j < tag && height[j] < startHeight){
tempSum = tempSum+height[j];
j++;
}
if(j == tag && height[j] < startHeight){
tag = i;
break;
}
// 综合是两个高块之间的总量减去其中小块的量
sum = sum + startHeight*(j-i-1)-tempSum;
i = j;
}
// 从右到左
i = len-1;
while (i > tag && height[i] == 0){
i--;
}
while (i > tag){
tempSum = 0; j = i-1;
startHeight = height[i];
// 找到下一个高度大于等于上一个目标块的
while (j > tag && height[j] < startHeight){
tempSum = tempSum+height[j];
j--;
}
if(j == tag && height[j] < startHeight){
break;
}
// 综合是两个高块之间的总量减去其中小块的量
sum = sum + startHeight*(i-j-1)-tempSum;
i = j;
}
return sum;
}
}
官方版本一(动态规划)
// 算法是,首先从左到右扫描,得到位置i左边最大的高度,然后从右边开始拿到位置i右边最大的高度
// 同一个位置i,这时就有了他左边最大的高度的值以及右边的最大的高度的值,在块的宽度为1的情况下,位置i盛水的高度(就是上图中位置i上有多少个那种蓝色块)
// 是取决于左右两边的最短边,因为宽度是1,所以直接拿到最短边的高度,然后直接用该高度减去位置i的高度,就能
// 拿到位置i上能盛多少水,最后加起来就是总的盛水量
class Solution {
public int trap(int[] height) {
int n = height.length;
if (n == 0) {
return 0;
}
int[] leftMax = new int[n];
leftMax[0] = height[0];
// 拿到每个位置i的左边部分最大的高度
for (int i = 1; i < n; ++i) {
leftMax[i] = Math.max(leftMax[i - 1], height[i]);
}
// 拿到每个位置i的右边部分最大的高度
int[] rightMax = new int[n];
rightMax[n - 1] = height[n - 1];
for (int i = n - 2; i >= 0; --i) {
rightMax[i] = Math.max(rightMax[i + 1], height[i]);
}
int ans = 0;
for (int i = 0; i < n; ++i) {
ans += Math.min(leftMax[i], rightMax[i]) - height[i];
}
return ans;
}
}
官方版本二(单调栈)
class Solution {
public int trap(int[] height) {
int ans = 0;
Deque<Integer> stack = new LinkedList<Integer>();
int n = height.length;
for (int i = 0; i < n; ++i) {
// stack的作用是拿到i两侧都比他高的块,因为两边高形成凹槽才能储水
while (!stack.isEmpty() && height[i] > height[stack.peek()]) {
int top = stack.pop();
// 这里主要用来处理现有未被处理的块中没有形成凹槽的情况,例如块的高度从小到低,那么pop以后栈就是空的
// 如果位置i-1是比位置i要高,那么就不会进入本逻辑,而是直接走下边的push
// 这里最终的实现结果是拿到形成凹槽的三个位置,然后进行计算他的储水量
// 这个过程是从左到右进行,计算完一个凹槽后,再从这个凹槽的右边块开始重新找下一个凹槽
if (stack.isEmpty()) {
break;
}
int left = stack.peek();
int currWidth = i - left - 1;
int currHeight = Math.min(height[left], height[i]) - height[top];
ans += currWidth * currHeight;
}
stack.push(i);
}
return ans;
}
}
官方版本三(双指针)
// 主要思想是使用双指针,两个指针指向的位置的高度,哪边矮,操作哪边
// 这是因为,假设right位置高度 > left位置高度,假设right位置高度是全局最高,那么储水量就是相当于left
// 的位置的高度,如果right位置不是最高,那么left与right之间肯定存在最高的高度,那么还是相对于left位置的高度
// 所以哪边矮操作哪边
// leftmax记录左边部分的最大高度,rightmax记录右边部分的最大高度
// 因为left是从0开始,而right是从n-1开始,那么left保持的就是各自左边部分最大的高度,leftmax就是位置
// left左边部分最大的高度
class Solution {
public int trap(int[] height) {
int ans = 0;
int left = 0, right = height.length - 1;
int leftMax = 0, rightMax = 0;
while (left < right) {
leftMax = Math.max(leftMax, height[left]);
rightMax = Math.max(rightMax, height[right]);
// 哪边小就一定哪边,假设其中一边是最高的,例如right=len-1,开始就是最高的,那么right
// 就不会移动,left会一直移动到最后,这样就计算出每个位置left的上方存储多少水,然后累计就是总量
// 如果right=len-1不是最高,那么首先是left移动,left肯定会移动到大于等于right的位置,该位置
// 可能是全局最高也可能不是,但是无论是不是,只要有比right高,那么就可以进行计算right位置
// 的储水量
if (height[left] < height[right]) {
ans += leftMax - height[left];
++left;
} else {
ans += rightMax - height[right];
--right;
}
}
return ans;
}
}
字符串相乘
题目链接:字符串相乘
个人版本一
class Solution {
public String multiply(String num1, String num2) {
String str = "";
if("0".equals(num1) || "0".equals(num2)){
return "0";
}
List<Integer> eleList = new ArrayList<>();
List<Integer[]> sumList = new ArrayList<>();
int num1Len = num1.length();
int num2Len = num2.length();
int flag = Integer.MAX_VALUE/10, i, j, count;
// 保证num1是最小的
if(num2Len < num1Len){
return multiply(num2, num1);
}
int[] num2Arr = new int[num2Len];
for(i=0; i<num2Len; i++){
num2Arr[i] = num2.charAt(i) - '0';
}
// 模拟短除法
for(i=num1Len-1; i>=0; i--){
if(num1.charAt(i) == '0') continue;
int toatl = 0;
eleList.clear();
sumList.clear();
int k1 = num1.charAt(i) - '0';
// 按照短除法最后一个开始乘,然后得到每一位的乘积
for(j=0; j<num2Len; j++){
int k2 = num2Arr[j];
eleList.add(k1*k2);
}
// 处理每一位的成绩,例如88*22,首先处理出来就是[16,16],就是2和88的乘积
j = 0;
count = 0;
while (j < eleList.size()){
// 判断乘10后是否溢出,如果没有溢出就直接一般的迭代乘法
if(toatl <= flag){
toatl = toatl*10 + eleList.get(j);
j++;
count++;
}else{
// sumList保存eleList中添加的数不超过当前的整型最大值的最小值,也就是里边的数再乘10就会超过整型最大值
sumList.add(new Integer[]{toatl, count});
toatl = 0;
count = 0;
}
}
sumList.add(new Integer[]{toatl, count});
// 处理sumList里边的元素,因为都在边界,不能
String tempStr = String.valueOf(sumList.get(0)[0]);
// 当总和函数中只有一个,那就只有一个答案,而不需要走合并
if(num1Len == 1 && sumList.size() == 1){
str = tempStr;
break;
}
for(j=1; j<sumList.size(); j++){
tempStr = mergeStr(tempStr, String.valueOf(sumList.get(j)[0]), sumList.get(j)[1]);
}
// 处理后缀0情况
count = num1Len-i-1;
// 将str和tempStr合并,就是相当于完成了某一个位的运算,然后继续高位的运算
str = mergeStr(tempStr, str, count);
}
return str;
}
// str1是高位的值,str2是低位的值
public String mergeStr(String str1, String str2, int span){
int end = str2.length()-span, i, j, carry = 0, k1, k2, sum;
// 存储存在分割的字符串存在前导0导致不计算的情况
if(end < 0){
for(j=0; j<-end; j++){
str2 = "0"+str2;
}
end = 0;
}
String leftPart = str2.substring(0, end);
String rightPart = str2.substring(end);
int leftPartLen = leftPart.length();
String tempStr = "";
i = leftPartLen-1;j = str1.length()-1;
while (i>=0 && j>=0){
k1 = str1.charAt(j) - '0';
k2 = str2.charAt(i) - '0';
sum = k1+k2+carry;
tempStr = sum%10 + tempStr;
carry = sum/10;
i--;
j--;
}
// 存在进位
if(carry != 0){
// 还存在进位
while (j>=0 && carry !=0 ){
k1 = str1.charAt(j) - '0';
sum = k1+carry;
tempStr = sum%10 + tempStr;
carry = sum/10;
j--;
}
if(carry == 1) {
tempStr = "1"+tempStr;
}
}
return str1.substring(0, j+1)+tempStr+rightPart;
}
}
官方版本一(竖式加法运算)
class Solution {
// 模仿竖式乘法,从低位开始相乘,高位末尾补零,最后相加,例如 123*23,首先是3*123=369,然后是2*123=246
// 然后2是高位,根据他的位数给结果后补0,2在导数倒数第2位,补一个0 ,就是2460,然后369+2460,使用字符串加法算法
public String multiply(String num1, String num2) {
if (num1.equals("0") || num2.equals("0")) {
return "0";
}
String ans = "0";
int m = num1.length(), n = num2.length();
for (int i = n - 1; i >= 0; i--) {
StringBuffer curr = new StringBuffer();
int add = 0;
for (int j = n - 1; j > i; j--) {
curr.append(0);
}
int y = num2.charAt(i) - '0';
for (int j = m - 1; j >= 0; j--) {
int x = num1.charAt(j) - '0';
int product = x * y + add;
curr.append(product % 10);
add = product / 10;
}
if (add != 0) {
curr.append(add % 10);
}
ans = addStrings(ans, curr.reverse().toString());
}
return ans;
}
public String addStrings(String num1, String num2) {
int i = num1.length() - 1, j = num2.length() - 1, add = 0;
StringBuffer ans = new StringBuffer();
while (i >= 0 || j >= 0 || add != 0) {
int x = i >= 0 ? num1.charAt(i) - '0' : 0;
int y = j >= 0 ? num2.charAt(j) - '0' : 0;
int result = x + y + add;
ans.append(result % 10);
add = result / 10;
i--;
j--;
}
ans.reverse();
return ans.toString();
}
}
官方版本二(竖式乘法运算)
class Solution {
// 就是把握到两数相乘的最大位数是m+n位,也就是例如2*23,1+2=3,最大就是3位,这可以证明的,m位数最大值是10^m-1
// 两个数分别有m位和n位,那这两个数的最大数相乘,(10^m-1)*(10^n-1)=10^(m+n)-10^m-10^n-1,该值比10^(m+n)要小
// 所以可以开辟一个长度为m+n的数组进行存储值,用来减少字符串运算
// 具体算法是,例如45*23,开辟长度为4的数组,从末尾开始乘,乘积放在i+j-1位置,因为该位置刚好乘出来的数的最低位对应的位置,45*23,首先是5*3=15,放在末尾,然后是5*2放在导数第二位,如此类推
// 最后得到数组是8,12,10,15,从末尾处理进位,例如15/10,结果加到前一位,余数5就是该位置的最终结果
// m+n是最多的位数,可能存在少于m+n的情况,就是m+n-1位,例如2*33,结果是0,6,6,实际上结果就是后边的66,那么就需要进一步判断
public String multiply(String num1, String num2) {
if (num1.equals("0") || num2.equals("0")) {
return "0";
}
int m = num1.length(), n = num2.length();
int[] ansArr = new int[m + n];
for (int i = m - 1; i >= 0; i--) {
int x = num1.charAt(i) - '0';
for (int j = n - 1; j >= 0; j--) {
int y = num2.charAt(j) - '0';
ansArr[i + j + 1] += x * y;
}
}
for (int i = m + n - 1; i > 0; i--) {
ansArr[i - 1] += ansArr[i] / 10;
ansArr[i] %= 10;
}
int index = ansArr[0] == 0 ? 1 : 0;
StringBuffer ans = new StringBuffer();
while (index < m + n) {
ans.append(ansArr[index]);
index++;
}
return ans.toString();
}
}
通配符匹配
个人版本一(动态规划)
class Solution {
public static boolean isMatch(String s, String p) {
int m = s.length(), n = p.length(), i, j;
boolean[][] f = new boolean[m+1][n+1];
f[0][0] = true;
// 初始化,s为空,p的*位置决定结构
for(i=1; i<=n; i++){
if(p.charAt(i-1) == '*'){
f[0][i] = f[0][i-1];
}
}
for(i=1; i<=m; i++){
for(j=1; j<=n; j++){
if(p.charAt(j-1) == '*'){
// f[i][j-1]:不匹配的时候
// f[i-1][j]:匹配一个或多个
f[i][j] = f[i][j-1] || f[i-1][j];
}else{
if(p.charAt(j-1) == s.charAt(i-1) || p.charAt(j-1) == '?'){
f[i][j] = f[i-1][j-1];
}
}
}
}
return f[m][n];
}
}
官方版本二(贪心算法)
// 主要思想是处理三种情况:第一种是:*v1*v2*v3*,也就是被*分割的情况,v1..可以是由小写字母以及?组成或者是空字符串,例如:p=*abc*cde*
// 因为*是可以代替任意字符的,那么我们就可以在s中找到第一个abc,然后再找到第二个cde,如果都能找到,那就说明匹配了
// 第二种是: v1*v2*,就是开头不是*,例如abc*cde*,这个时候就要严格去开头匹配abc,剩下的类似
// 第三种是:*v1*v2,也就是严格匹配末尾
// 上述三种其实还囊括了,两头都没*的情况
// 该方法比动态规划的优越在于,动态规划遍历了所有情况,而*是可以代表多个任意字符的,多个*相邻就会产生额外的空间以及无意义的操作
class Solution {
public boolean isMatch(String s, String p) {
int sRight = s.length(), pRight = p.length();
// 单独处理末尾无*的情况
while (sRight > 0 && pRight > 0 && p.charAt(pRight - 1) != '*') {
if (charMatch(s.charAt(sRight - 1), p.charAt(pRight - 1))) {
--sRight;
--pRight;
} else {
return false;
}
}
if (pRight == 0) {
return sRight == 0;
}
// sIndex,
int sIndex = 0, pIndex = 0;
// sRecord和pRecord可以用来处理首字母不是*,然后出现匹配不相等的情况
// 以及出现匹配重复问题,如下例子:s="abcabczzzde", p="*abc???de*"
// 开头出现两个abc,第一个就被匹配了,实际上应该被匹配的是第二个abc
// sRecord和pRecord就可以用来记录起始位置,sIndex和pIndex是实际操作
// 的指针,用于贪婪匹配过程,pIndex和sIndex开始会将p开头 的abc和s开头的abc匹配
// 而后使用sRecord以及pRecord再回到最初的位置的进行匹配,最终匹配到第二个abc
// 往后就匹配成功了,贪婪匹配匹配到了第二个abc使得最终匹配成功
int sRecord = -1, pRecord = -1;
while (sIndex < sRight && pIndex < pRight) {
// 处理多个*的情况
if (p.charAt(pIndex) == '*') {
++pIndex;
sRecord = sIndex;
pRecord = pIndex;
} else if (charMatch(s.charAt(sIndex), p.charAt(pIndex))) {
// 处理字符匹配过程
++sIndex;
++pIndex;
} else if (sRecord != -1 && sRecord + 1 < sRight) {
++sRecord;
sIndex = sRecord;
pIndex = pRecord;
} else {
return false;
}
}
return allStars(p, pIndex, pRight);
}
public boolean allStars(String str, int left, int right) {
for (int i = left; i < right; ++i) {
if (str.charAt(i) != '*') {
return false;
}
}
return true;
}
public boolean charMatch(char u, char v) {
return u == v || v == '?';
}
}