leetcode11-17

11. 盛最多水的容器

给定 n 个非负整数 a*1,*a*2,…,*a*n,每个数代表坐标中的一个点 (*i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

说明:你不能倾斜容器,且 n 的值至少为 2。

解:双指针

class Solution {
    public int maxArea(int[] height) {
        int start = 0;
        int end = height.length-1;
        int max = 0;
        while(start<end){
            int h = Math.min(height[start],height[end]);
            max = Math.max(max,h*(end-start));
            if(height[start]>height[end]){
                end--;
            }else{
                start++;
            }
        }
        return max;
    }
}

12. 整数转罗马数字

解:操作题

class Solution {
    public String intToRoman(int num) {
         int[] values = {1000,900,500,400,100,90,50,40,10,9,5,4,1};
         String[] strs = {"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
         StringBuilder sb = new StringBuilder();
         for(int i=0;i<values.length;i++) {
             while(num >= values[i]) {
                 num -= values[i];
                 sb.append(strs[i]);
             }
         }
        return sb.toString();
    }
}

13. 罗马数字转整数

class Solution {
public:
    int romanToInt(string s) {
        int res=0;
        int lastValue=0;
        int digit;
        for(int i=s.size()-1;i>=0;i--){
            switch(s[i]){
                case 'I': digit=1; break;
                case 'V': digit=5; break;
                case 'X': digit=10; break;
                case 'L': digit=50; break;
                case 'C': digit=100; break;
                case 'D': digit=500; break;
                case 'M': digit=1000; break;
            }
            if(digit>=lastValue){
                res+=digit;
                lastValue=digit;
            }
            else res-=digit;
        }
        return res;
    }

};

14. 最长公共前缀

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 ""

解:取数组中的一个作为前缀,和其他剩余所有匹配。每次都把前缀缩小一位

class Solution {
    public String longestCommonPrefix(String[] strs) {
        if (strs.length == 0) return "";
        String prefix = strs[0];
        for (int i = 1; i < strs.length; i++)
            while (strs[i].indexOf(prefix) != 0) {
                prefix = prefix.substring(0, prefix.length() - 1);
                if (prefix.isEmpty()) return "";
            }        
        return prefix;
    }
}

15. 三数之和

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

解:先排序,然后固定a,求bc之和为-a的情况,即转化为2数之和的问题,需要注意的是去重。

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> list = new ArrayList<>();
        if (nums == null || nums.length == 0) return list;
        Arrays.sort(nums);
        for (int i = 0; i < nums.length; i++) {
            //去重
            if (i >= 1 && nums[i] == nums[i - 1]) {
                continue;
            }
            int start = i + 1;
            int end = nums.length - 1;
            while (start < end) {
                int sum = nums[start] + nums[end];
                if (sum < -nums[i]) {
                    start++;
                    while(nums[start] == nums[start-1] && start<end){
                        start++;
                    }
                } else if (sum > -nums[i]) {
                    end--;
                    while(nums[end] == nums[end+1] && start<end){
                        end--;
                    }
                } else {
                    List<Integer> l = Arrays.asList(nums[i], nums[start], nums[end]);
                    list.add(l);
                    start++;
                    end--;
                    while(nums[start] == nums[start - 1] && nums[end] == nums[end + 1] && start < end){
                        start++;
                        end--;
                    }
                }
            }
        }
        return list;
    }
}

16. 最接近的三数之和

解:同三数之和的思想,也是固定一个,然后在后面进行两数的双指针操作

class Solution {
    public int threeSumClosest(int[] nums, int target) {
        List<List<Integer>> list = new ArrayList<>();
        if (nums == null || nums.length == 0) return -1;
        Arrays.sort(nums);
        int result=0;
        int minAbs = Integer.MAX_VALUE;
        for (int i = 0; i < nums.length; i++) {
            int start = i + 1;
            int end = nums.length - 1;
            while (start < end) {
                int sum = nums[i] + nums[start] + nums[end];
                int abs = Math.abs(sum-target);
                if(abs<minAbs){
                    minAbs = abs;
                    result = sum;
                }
                if(sum<target){
                    ++start;
                }else{
                    --end;
                }

            }
        }
        return result;
    }
}

17. 电话号码的字母组合

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

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

img

解:回溯算法,对于29来说,先2里面取一个a,然后下一层取9中的一个w,得到结果,之后回退到2里面的a,再从9中取y,最后9中取完后回退到2,取下一个b。

class Solution {
    public List<String> letterCombinations(String digits) {
        List<String> result = new ArrayList<>();
        if(digits == null ||"".equals(digits.trim())) return result;
        Map<Integer,char[]> map = new HashMap<>();
        map.put(2,new char[]{'a','b','c'});
        map.put(3,new char[]{'e','d','f'});
        map.put(4,new char[]{'g','h','i'});
        map.put(5,new char[]{'j','k','l'});
        map.put(6,new char[]{'m','n','o'});
        map.put(7,new char[]{'p','q','r','s'});
        map.put(8,new char[]{'t','u','v'});
        map.put(9,new char[]{'w','x','y','z'});
        char[] chars = digits.toCharArray();
        StringBuilder sb = new StringBuilder();
        dfs(chars,result,0,sb,map);
        return result;
    }

    private void dfs(char[] chars, List<String> result, int start, StringBuilder sb, Map<Integer,char[]> map) {
        if(sb.length() == chars.length){
            result.add(sb.toString());
        }
        for (int i = start; i < chars.length; i++) {
            char[] cs = map.get(chars[i]-'0');
            for (char c : cs) {
                sb.append(c);
                dfs17(chars,result,i+1,sb,map);
                sb.deleteCharAt(sb.length()-1);
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/lengyuedanhen/article/details/81838070
今日推荐