Jerry's Blog

Recording what I learned everyday

View on GitHub


23 December 2019

LeetCode(69) -- 18, 19

by Jerry Zhang

P18. 4Sum (Medium)

My Solution

public class P18_4Sum {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        Arrays.sort(nums);
        List<List<Integer>> res = new ArrayList<>();
        for (int i = 0; i < nums.length - 3; i++) {
            for (int j = i + 1; j < nums.length - 2; j++) {
                int l = j + 1;
                int r = nums.length - 1;
                while (l < r) {
                    if (nums[i] + nums[j] + nums[l] + nums[r] == target) {
                        ArrayList<Integer> list = new ArrayList<>(Arrays.asList(nums[i], nums[j], nums[l], nums[r]));
                        res.add(list);
                        l++;
                        r--;
                        while (l < r && nums[l] == nums[l - 1]) {
                            l++;
                        }
                        while (l < r && nums[r] == nums[r + 1]) {
                            r--;
                        }
                    } else if (nums[i] + nums[j] + nums[l] + nums[r] < target) {
                        l++;
                        while (l < r && nums[l] == nums[l - 1]) {
                            l++;
                        }
                    } else {
                        r--;
                        while (l < r && nums[r] == nums[r + 1]) {
                            r--;
                        }
                    }
                }
                while (j + 1 < nums.length - 2 && nums[j + 1] == nums[j]) {
                    j++;
                }
            }
            while (i + 1 < nums.length - 3 && nums[i + 1] == nums[i]) {
                i++;
            }
        }
        return res;
    }

    public static void main(String[] args) {
        List<List<Integer>> lists = new P18_4Sum().fourSum(new int[]{-1, -5, -5, -3, 2, 5, 0, 4}, -7);
        System.out.println("lists = " + lists);
    }
}

The Best Solution

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
		ArrayList<List<Integer>> res = new ArrayList<List<Integer>>();
		int len = nums.length;
		if (nums == null || len < 4)
			return res;

		Arrays.sort(nums);

		int max = nums[len - 1];
		if (4 * nums[0] > target || 4 * max < target)
			return res;

		int i, z;
		for (i = 0; i < len; i++) {
			z = nums[i];
			if (i > 0 && z == nums[i - 1])// avoid duplicate
				continue;
			if (z + 3 * max < target) // z is too small
				continue;
			if (4 * z > target) // z is too large
				break;
			if (4 * z == target) { // z is the boundary
				if (i + 3 < len && nums[i + 3] == z)
					res.add(Arrays.asList(z, z, z, z));
				break;
			}

			threeSumForFourSum(nums, target - z, i + 1, len - 1, res, z);
		}

		return res;
	}

    public void threeSumForFourSum(int[] nums, int target, int low, int high, ArrayList<List<Integer>> fourSumList,
			int z1) {
		if (low + 1 >= high)
			return;

		int max = nums[high];
		if (3 * nums[low] > target || 3 * max < target)
			return;

		int i, z;
		for (i = low; i < high - 1; i++) {
			z = nums[i];
			if (i > low && z == nums[i - 1]) // avoid duplicate
				continue;
			if (z + 2 * max < target) // z is too small
				continue;

			if (3 * z > target) // z is too large
				break;

			if (3 * z == target) { // z is the boundary
				if (i + 1 < high && nums[i + 2] == z)
					fourSumList.add(Arrays.asList(z1, z, z, z));
				break;
			}

			twoSumForFourSum(nums, target - z, i + 1, high, fourSumList, z1, z);
		}

	}


    private void twoSumForFourSum(int[] nums,int target,int low,int high,List<List<Integer>> result,int z1,int z2){

        if(low>=high) return;
        int max = nums[high];
        if(2*nums[low]>target||2*max<target){
            return;
        }

        int i=low;
        int j=high;
        int sum ;

        while (i<j){
            sum = nums[i]+nums[j];
            if(sum==target){
                result.add(Arrays.asList(z1,z2,nums[i],nums[j]));
                i++;
                j--;
                while(i<j&&nums[i]==nums[i-1]) i++;
                while (i<j&&nums[j]==nums[j+1]) j--;

            }else if(sum<target){
                i++;
            }else{
                j--;
            }
        }
    }
}

P19. Remove Nth Node From End of List (Medium)

Given a linked list, remove the n-th node from the end of list and return its head.

My Solution

public class P19_RemoveNthNodeFromEndofList {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode detector = head;
        for (int i = 0; i < n; i++) {
            detector = detector.next;
        }
        if (detector == null) {
            return head.next;
        }
        ListNode curr = head;
        while (detector.next != null) {
            curr = curr.next;
            detector = detector.next;
        }
        curr.next = curr.next.next;
        return head;
    }
}

100%

tags: LeetCode