LeetCode 分治篇(50、17)

50. Pow(x, n)

实现 pow(x, n) ,即计算 x 的 n 次幂函数。

示例 1:

输入: 2.00000, 10
输出: 1024.00000
示例 2:

输入: 2.10000, 3
输出: 9.26100
示例 3:

输入: 2.00000, -2
输出: 0.25000
解释: 2-2 = 1/22 = 1/4 = 0.25
说明:

-100.0 < x < 100.0
n 是 32 位有符号整数,其数值范围是 [−231, 231 − 1] 。

思路

//确定边界,n可以为负数
//暴力法
//分治(幂运算)
//迭代(幂运算),牛顿迭代法

solution 1 暴力

//超时
class Solution {
    public double myPow(double x, int n) {
        double re = 1;
        if (n<0){
            for (int i = 0; i <-n;i++){
                re = re*(1/x);
            }
        }
        if (n>0){
             for (int i = 0; i<n; i ++){
                re = re*x;
            }
        }
        return re;
    }
}

solution2 分治(幂运算)

//时间复杂度(logN)
class Solution {
    public double myPow(double x, int n) {
        return n>=0 ? helper(x,n):1.0/helper(x,-n);
    }
    public double helper(double x, int n){
        if (n==0) return 1.0;
        //下一层,子问题
        double re = helper(x,n/2);
        return n%2==0 ? re*re : re*re*x;
    }
}

solution3 迭代

//-n必须为long类型
class Solution {
    public double myPow(double x, int n) {
        long N = n;
        return n >= 0?helper(x,N):1.0/helper(x,-N);
    }
    public double helper(double x, long n){
        double res = 1.0;
        double contribute = x;
        while (n>0){
            if (n%2 == 1){ //为奇数时要多乘一个本身
                res *= contribute;
            }
            contribute *= contribute; //下一次要迭代的
            n /= 2;
        }
        return res;
    }  
}

17. 电话号码的字母组合

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

输入:"23"
输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
说明:
尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。

solution1递归回溯

//时间复杂度为3^N*4^M (n+m=digits.length())
class Solution {
    public List<String> letterCombinations(String digits) {
        List<String> ans =  new ArrayList();
        if (digits == null || digits.equals("")) return ans;
        Map<Character, String> map = new HashMap<Character,String>();
        map.put('2',"abc");
        map.put('3',"def");
        map.put('4',"ghi");
        map.put('5',"jkl");
        map.put('6',"mno");
        map.put('7',"pqrs");
        map.put('8',"tuv");
        map.put('9',"wxyz");
        helper(digits,ans,"",map,0);
        return ans;
    }
    public void helper(String digits,List<String> ans,String curr,
                        Map<Character,String> map,int index){
           //终止条件
        if (index == digits.length()) {
            ans.add(curr);
            return;
        }
          //当前层,下一层
        String letters = map.get(digits.charAt(index));
        for (int i = 0;i < letters.length();i++){
            helper(digits,ans,curr+letters.charAt(i),map,index+1);
        }
    }
}
//总结
// String判空  str==null || str.equals("")
// list转String  String join = String.join(",", list);
// char[]转String String str = String.valueOf(cha);
// String转char[] char[] cha = String.toCharArray();
// String转char char c = String.charAt( index );

solution2 队列

class Solution {
    public List<String> letterCombinations(String digits) {
        List<String> ans =  new ArrayList();
        if (digits == null || digits.equals("")) return ans;
        Map<Character, String> map = new HashMap<Character,String>();
        map.put('2',"abc");
        map.put('3',"def");
        map.put('4',"ghi");
        map.put('5',"jkl");
        map.put('6',"mno");
        map.put('7',"pqrs");
        map.put('8',"tuv");
        map.put('9',"wxyz");
        ans.add("");
        for (int i=0; i<digits.length(); i++){
            String letters = map.get(digits.charAt(i));
            int size = ans.size(); //数组长度计算不能放在for循环里,长度会一直变化
            for (int j=0; j < size;j++){
                String str = ans.remove(0);//队列弹出第一个元素
                for (int k = 0; k < letters.length(); k++){
                    ans.add(str+letters.charAt(k));
                }
            }
        }
        return ans;
    } 
}
posted @ 2020-07-08 21:27  gg12138  阅读(118)  评论(0编辑  收藏  举报