LeetCode-Java(04)

15. 三数之和

LeetCode-Java(04)_第1张图片

 固定第一个数,从后面找第二个和的三个数的和等于第一个数,转化为两数之和问题。比target大,则l--,否则r++,直到找到三个数

class Solution {
    public List> threeSum(int[] nums) {
        List> res = new ArrayList<>();
        
        Arrays.sort(nums);
        
        for (int i = 0; i < nums.length - 2; i++) {
            if (i > 0 && nums[i] == nums[i - 1]) continue;
            
            int low = i + 1;
            int high = nums.length - 1;
            int target = -nums[i];
            
            // two pointer to solve two sum
            while (low < high) {
                int l = nums[low];
                int h = nums[high];
                
                if (l + h < target) low++;
                else if (l + h > target) high--;
                else {
                    res.add(Arrays.asList(nums[i], l, h));
                    
                    // attention: low < high
                    while (low < high && nums[low + 1] == nums[low]) low++;
                    // new nums[low] val
                    low++;
                }
            }
        }
        
        return res;
    }
}

16. 最接近的三数之和

LeetCode-Java(04)_第2张图片

 和上一题一样,之多加了一个判断语句 if(Math.abs(target - sum) < Math.abs(target - ans))

class Solution {
    public int threeSumClosest(int[] nums, int target) {
        Arrays.sort(nums);
        int ans = nums[0] + nums[1] + nums[2];
        for(int i=0;i target)
                    end--;
                else if(sum < target)
                    start++;
                else
                    return ans;
            }
        }
        return ans;
    }
}

17. 电话号码的字母组合

LeetCode-Java(04)_第3张图片回溯法

class Solution {
	String[] letter_map = {" ","*","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
	public List letterCombinations(String digits) {
		if(digits==null || digits.length()==0) {
			return new ArrayList<>();
		}
		iterStr(digits, new StringBuilder(), 0);
		return res;
	}

	List res = new ArrayList<>();
	
	//递归函数
	public void iterStr(String digits,StringBuilder sb, int index){
		//"ad" index==digits.length()==2 满足条件 存入res
		if(index==digits.length()){ 
			res.add(sb.toString());
			return;
		}
		char c=digits.charAt(index);
		int pos=c-'0'; // 23 对应成字符串数组中的下标
		String letterstr=letter_map[pos]; // 得到字符串
		for(int i=0;i

队列

class Solution {

	public List letterCombinations(String digits) {
		if(digits==null || digits.length()==0) {
			return new ArrayList();
		}
		//一个映射表,第二个位置是"abc“,第三个位置是"def"。。。
		//这里也可以用map,用数组可以更节省点内存
		String[] letter_map = {
			" ","*","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"
		};
		List res = new ArrayList<>();
		//先往队列中加入一个空字符
		res.add("");
		for(int i=0;i

18. 四数之和

LeetCode-Java(04)_第4张图片

第一步肯定还是先排序,和三数之和一样的思想,就是剪枝操作多一点。

  1. 在确定第一个数之后,如果 nums[i]+nums[i+1]+nums[i+2]+nums[i+3]>target,说明此时剩下的三个数无论取什么值,四数之和一定大于 target,因此退出第一重循环;
  2. 在确定第一个数之后,如果 nums[i]+nums[n−3]+nums[n−2]+nums[n−1]
  3. 在确定前两个数之后,如果 nums[i]+nums[j]+nums[j+1]+nums[j+2]>target,说明此时剩下的两个数无论取什么值,四数之和一定大于target,因此退出第二重循环;
  4. 在确定前两个数之后,如果 nums[i]+nums[j]+nums[n−2]+nums[n−1]

这里i是第一重取值从0到length-3,j是第二重,取值从i+1到length-2,固定两个以后,取right和left为剩下的左右端点,接下来的分析情况就和三数之和一样了。

class Solution {
    public List> fourSum(int[] nums, int target) {
        List> quadruplets = new ArrayList>();
        if (nums == null || nums.length < 4) {
            return quadruplets;
        }
        Arrays.sort(nums);
        int length = nums.length;
        for (int i = 0; i < length - 3; i++) {
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }
            if ((long) nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) {
                break;
            }
            if ((long) nums[i] + nums[length - 3] + nums[length - 2] + nums[length - 1] < target) {
                continue;
            }
            for (int j = i + 1; j < length - 2; j++) {
                if (j > i + 1 && nums[j] == nums[j - 1]) {
                    continue;
                }
                if ((long) nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target) {
                    break;
                }
                if ((long) nums[i] + nums[j] + nums[length - 2] + nums[length - 1] < target) {
                    continue;
                }
                int left = j + 1, right = length - 1;
                while (left < right) {
                    long sum = (long) nums[i] + nums[j] + nums[left] + nums[right];
                    if (sum == target) {
                        quadruplets.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
                        while (left < right && nums[left] == nums[left + 1]) {
                            left++;
                        }
                        left++;
                        while (left < right && nums[right] == nums[right - 1]) {
                            right--;
                        }
                        right--;
                    } else if (sum < target) {
                        left++;
                    } else {
                        right--;
                    }
                }
            }
        }
        return quadruplets;
    }
}

你可能感兴趣的:(LeetCode刷题,java,开发语言,算法)