罗马数字转整数_三数之和_最接近的三数之和_电话号码的字母组合_四数之和

这篇博客详细介绍了几种经典的计算机算法问题,包括罗马数字转整数、三数之和、最接近的三数之和以及四数之和的解决方案。通过排序和双指针技术,有效地解决了这些问题。对于每个问题,都提供了清晰的解题思路和Java代码实现,便于理解与应用。
摘要由CSDN通过智能技术生成

目录

 

罗马数字转整数

三数之和

 最接近的三数之和

电话号码的字母组合

 四数之和


罗马数字转整数

解题思路:当前值和下一个值进行比较,如果小的话就做减法,如果是大的值就做加法

class Solution {
    public int romanToInt(String s) {
        if(s == null || s.length() == 0){
            return 0;
        }
        Map<Character, Integer> map = new HashMap<Character, Integer>();
        map.put('I', 1);
        map.put('V', 5);
        map.put('X', 10);
        map.put('L', 50);
        map.put('C', 100);
        map.put('D', 500);
        map.put('M', 1000);
        int sum = 0;
        char[] chas = s.toCharArray();
        for(int i = 0; i < chas.length - 1; i++){
            int curValue = map.get(chas[i]);
            int nextValue = map.get(chas[i+1]);
            if(curValue < nextValue){
                sum -= curValue;
            }
            else{
                sum += curValue;
            }
        }
        int lastValue = map.get(chas[chas.length-1]);
        sum += lastValue;
        return sum;
    }
}

三数之和

class Solution {
    //对撞指针;注意去掉重复的值
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        if(nums == null || nums.length <= 2){
            return res;
        }
        Arrays.sort(nums);//先进行排序
        for(int i = 0; i <= nums.length - 3; i++){
            //去掉重复的内容
            if(i == 0 || nums[i] > nums[i-1]){
                int j = i + 1;
                int k = nums.length - 1;
                while(j < k){
                    if(nums[i] + nums[j] + nums[k] == 0){
                        List<Integer>  element = new ArrayList<Integer>();
                        element.add(nums[i]);
                        element.add(nums[j]);
                        element.add(nums[k]);
                        j ++;
                        k --;
                        res.add(element);
                        //去掉重复的
                        while(j < k && nums[j] == nums[j - 1]){
                            j ++;
                        }
                        while(k > j && nums[k] == nums[k+1]){
                            k --;
                        }
                    }
                    else if(nums[i] + nums[j] + nums[k] > 0){
                        k --;
                    }
                    else{
                        j ++;
                    }
                }
            }
        }
        return res;
    }
}

 最接近的三数之和

class Solution {
    public int threeSumClosest(int[] nums, int target) {
        if(nums ==  null || nums.length <= 2){
            return  -1;
        }
        int resSum = Integer.MAX_VALUE;
        Arrays.sort(nums);//先对数组进行排序
        for(int i = 0; i <= nums.length - 3; i ++){
            if(i == 0 ||(i > 0 && nums[i] != nums[i-1]) ){
                int j = i + 1;
                int k = nums.length - 1;
                while(j < k){
                    //找到更接近的值
                    int sum = nums[i] + nums[j] + nums[k];
                    //System.out.println(sum);
                    if(resSum == Integer.MAX_VALUE){
                        resSum = sum;
                    }
                    else if(Math.abs(sum - target) < Math.abs(resSum - target)){
                        resSum = sum;
                    }
                    //值更大的话
                    if(sum > target){
                        k --;
                    }
                    else if(sum < target){
                        j ++;
                    }
                    else{
                        return sum;//如果有相等的值的话就直接返回最终的结果
                    }
                }
            }
           
        }
        return resSum;
    }
}

首先进行数组排序,时间复杂度为O(nlogn)

在数组nums中,进行遍历,每遍历一个值利用其下标i,形成一个固定值nums[j]

再使用前指针指向start = i + 1处,后指针指向end = nums.length - 1处,也就是结尾处

根据sum = nums[i] + nums[j] + nums[k]的结果,判断sum与目标target的距离,如果更近则更新结果ans

同时判断sum与target的大小关系,因为数组有序,如果sum > target,则k --,如果sum < target 则j++,如果sum == target则说明距离为0直接返回结果。

时间复杂度:

遍历整个过程,固定值为n次,双指针为n次,时间复杂度为O(nlogn) + O(n * n)

其中排序的时间复杂度为O(nlogn)

电话号码的字母组合

class Solution {
    private List<String> res = new ArrayList<>();
    public List<String> letterCombinations(String digits) {
        if(digits == null || digits.length() == 0){
            //这里不能直接返回null,因为null和[]是不同的
            return res;
        }
        String[] strs = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
        StringBuilder sb = new StringBuilder();
        dfs(0, digits, sb, strs);
        return res;
    }
    public void dfs(int index, String digits, StringBuilder sb, String[] strs){
        if(index == digits.length()){
            res.add(new String(sb.toString()));
            return;//这里少了return
        }
        char c = digits.charAt(index);
        char[] candidates = strs[c-'0'].toCharArray();
        for(int i = 0; i < candidates.length; i++){
            sb.append(candidates[i] + "");
            dfs(index+ 1, digits, sb, strs);
            sb.deleteCharAt(sb.length() - 1);//删除最后一个字符
        }
    }
}

 四数之和

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
         List<List<Integer>> res = new ArrayList<>();
        if(nums == null || nums.length <= 3){
            return res;
        }
        Arrays.sort(nums);//先进行排序
        for(int i = 0; i <= nums.length - 4; i++){
            //去掉重复的内容
            if(i == 0 || nums[i] > nums[i-1]){
                for(int j = i + 1; j <= nums.length -  3; j ++){
                    if(j == i + 1|| nums[j] > nums[j-1]){
                        int k = j + 1;
                        int l = nums.length - 1;
                        while(k < l){
                            if(nums[i] + nums[j] + nums[k] + nums[l] == target){
                                List<Integer>  element = new ArrayList<Integer>();
                                element.add(nums[i]);
                                element.add(nums[j]);
                                element.add(nums[k]);
                                element.add(nums[l]);
                                k ++;
                                l --;
                                res.add(element);
                                //去掉重复的
                                while(k < l && nums[k] == nums[k-1]){
                                    k ++;
                                }
                                while(l > k && nums[l] == nums[l+1]){
                                    k --;
                                }
                            }
                            else if(nums[i] + nums[j] + nums[k] + nums[l] > target){
                                l --;
                            }
                            else{
                                k ++;
                            }
                        }
                    }
                    
                }
            }
        }
        return res;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值