Day27_Backtracking, Leetcode 93, 78, 90

Leetcode 93

-Leetcode

题目的第一想法:

这道题有几个有些吊诡的地方卡了我一段时间。首先是结束的条件,我最一开始以为忽略了四个有效数字的限制,以为只要当前的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

-Leetcode

题目的第一想法:

这道题的大体思路就是不需要判断放入条件的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

-Leetcode

题目的第一想法:

和上一道题的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来解决

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值