剑指 Offer II 087. 复原 IP / 剑指 Offer II 088. 爬楼梯的最少成本

**剑指 Offer II 087. 复原 IP **【中等题】

思路:

与主站93题重复
93. 复原 IP 地址

【回溯】

这题与一般的回溯法的不同点在于,这题是采用数组存储递归过程中的ip,递归完成之后返回进行其他递归的时候新的数据会把原数组覆盖,因此递归完成之后不用考虑将数组回溯成递归前状态。
思路写在代码注释里,参考自评论区大佬yukiyama

代码:

class Solution {

    List<String> list;
    int[] ip;
    String s;
    int n;

    public List<String> restoreIpAddresses(String s) {
        this.list = new ArrayList<>();
        this.ip = new int[4];
        this.s = s;
        this.n = s.length();
        backtrack(0,0);
        return list;
    }

    public void backtrack(int idx,int depth){
        if (depth == 4){//depth = 4 递归函数必须返回
            if (idx == n){//如果刚好字符串分割完毕,说明找到一个合法的ip地址,将其加入list列表
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < 4; i++) {
                    sb.append(ip[i]);
                    if (i != 3){
                        sb.append('.');
                    }
                }
                list.add(sb.toString());
            }
            //否则,说明未合法分割,递归函数直接返回
            return;
        }
        //剪枝
        //如果剩余待判断字符不足提供剩余ip节数,或者剩余待判断字符超过剩余ip节数的最大字符数,函数直接返回
        if (n - idx < 4 - depth || n - idx > (4 - depth) * 3){
            return;
        }
        //计算当前待分段ip的值
        int seg = 0;
        for (int i = idx; i < idx + 3 && i < n; i++) {
            seg = seg * 10 + (s.charAt(i)-'0');
            //剪枝
            //ip分段合法性检查 如果当前分段ip不合法,当前层的递归函数直接终止
            if (seg > 255 || seg < 0){
                return;
            }
            //ip分段通过合法性检查后,将其存入ip数组
            ip[depth] = seg;
            //从i+1位开始继续检查ip分段,此时ip分段检查的深度+1
            backtrack(i+1,depth+1);
            //如果当前ip分段是0 那么它只能作为单独的一节,当前递归直接返回,不必再考察后边的i
            //(递归函数每次只判断一个ip分段,ip分段合法则任务完成,因此需要直接返回)
            if (seg == 0){
                return;
            }
        }
    }
}

剑指 Offer II 088. 爬楼梯的最少成本【简单题】

思路:【动态规划】

见代码注释。

746. 使用最小花费爬楼梯

代码:

class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int n = cost.length;
        //dp数组用来存储到达第i个位置的花费,根据题目规则,最后一步可能刚好跳到最后一级台阶,也可能跳到最后一级台阶的上面,因此dp的长度为n+1
        int[] dp = new int[n+1];
        for (int i = 2; i <= n; i++) {
            //动态转移公式如下:
            //到达第i个位置的花费 = min{到达第i-1位置的花费dp[i-1]+在第i-1位置跳一级台阶达到第i个位置的花费cost[i-1] , 到达第i-2位置的花费dp[i-2] + 在第i-2位置跳两级台阶到达第i个位置的花费 cost[i-2] }
            dp[i] = Math.min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]);
        }
        //我们只需跳到最后一级
        return dp[n];
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值