Leetcode 93
题目的第一想法:
这道题有几个有些吊诡的地方卡了我一段时间。首先是结束的条件,我最一开始以为忽略了四个有效数字的限制,以为只要当前的index正好在字符的结尾就可以了。但之后发现只有这一个数值作为限制是不够的。于是我又加了一个loop数的限制。条件是当loop为4且当前index在字符结尾处时,加入当前储存的字符并返回。另一个问题是for loop的建立。我觉得每次for loop都小于三次会对trim比较有帮助,然后每次数值到数组结尾的传递则依靠于recursion来解决于是整个的结构就好像有点奇怪。最后是对于数字的判断。有两个条件,一是当数字不为零且小于256,二是数字为零,当数字为零是就break整个loop。
class Solution {
public List<String> restoreIpAddresses(String s) {
List<String> rlist = new ArrayList<>();
StringBuilder sb = new StringBuilder(s);
StringBuilder temp = new StringBuilder();
helper(rlist, sb, temp, 0, 0);
return rlist;
}
void helper(List<String> rlist, StringBuilder s, StringBuilder temp, int index, int loop){
if(loop == 4 && index == s.length()){
rlist.add(temp.substring(0, temp.length() - 1));
return;
}else if(loop >= 4 && index < s.length()) return;
for(int i = index + 1; i < index + 4; i++){
if(i <= s.length() && Integer.valueOf(s.substring(index, i)) <= 255 && Integer.valueOf(s.substring(index, i)) > 0){
temp.append(s.substring(index, i) + ".");
helper(rlist, s, temp, i, loop + 1);
temp.delete(temp.length() - s.substring(index, i).length() - 1, temp.length());
}else if(i <= s.length() && Integer.valueOf(s.substring(index, i)) == 0){
temp.append("0.");
helper(rlist, s, temp, index + 1, loop + 1);
temp.delete(temp.length() - s.substring(index, i).length() - 1, temp.length());
break;
}
}
}
}
看完代码随想录之后的想法:
发现从结构来看,有一个判断条件method和然后不限制loop的次数在结构上会好看很多。
Leetcode 78
题目的第一想法:
这道题的大体思路就是不需要判断放入条件的backtracking,只需要把放入条件拿走、无论list里面有什么都加到返回表里面就好了。但对于空表的放入在结构上还是挺巧妙的。
class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> rlist = new ArrayList<>();
List<Integer> list = new ArrayList<>();
rlist.add(list);
helper(rlist, list, nums, 0);
return rlist;
}
void helper(List<List<Integer>> rlist, List<Integer> list, int[] nums, int index){
for(int i = index; i < nums.length; i++){
list.add(nums[i]);
rlist.add(new ArrayList<>(list));
helper(rlist, list, nums, i + 1);
list.remove(list.size() - 1);
}
}
}
看完代码随想录之后的想法:
这个子集是看所有节点,集合是看所有叶节点的区别我自己还是没想到的。
Leetcode 90
题目的第一想法:
和上一道题的subset很像但是需要排开所有的重复的数字。底层逻辑是假设有一个2有重复,接受第一个2,在同一树枝上继续进行,但跳过接下来的所有重复的数字。在这里可以使用一个loop来对i进行操作。但是需要注意的是我们需要拿到当前的数字,不然的话edge case会很难涉及到。
class Solution {
public List<List<Integer>> subsetsWithDup(int[] nums) {
List<List<Integer>> rlist = new ArrayList<>();
List<Integer> list = new ArrayList<>();
Arrays.sort(nums);
helper(rlist, list, nums, 0);
return rlist;
}
void helper(List<List<Integer>> rlist, List<Integer> list, int[] nums, int index){
rlist.add(new ArrayList<>(list));
for(int i = index; i < nums.length; i++){
list.add(nums[i]);
helper(rlist, list, nums, i + 1);
int num = list.remove(list.size() - 1);
while(i < nums.length - 1 && nums[i + 1] == num) i++;
}
}
}
看完代码随想录之后的想法:
看到题解后发现这题也可以使用used来解决