Algorithm: Two pointers

Double pointers are generally used for two purposes:

1) In the sorted array, search for the target answer. Or in the case of the pursuit of the largest or the smallest that cannot change the position of the element, the answer is pursued according to the size without sorting (LC11).

2) Determine the position of an element in the linked list.


Array search:

11. Container With Most Water

15. 3Sum

16. 3Sum Closest

26. Remove Duplicates from Sorted Array


The linked list determines the elements:

19. Remove Nth Node From End of List


11. Container With Most Water

Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.

class Solution {
    public int maxArea(int[] height) {
        int left = 0;
        int right = height.length - 1;
        int res = 0;
        while (left < right) {
            int area = Math.min(height[left], height[right]) * (right - left);
            res = area > res ? area : res;
            if (height[left] > height[right]) {
                --right;
            } else {
                ++left;
            }
        }
        return res;
    }
}


15. 3Sum

Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

Note:

The solution set must not contain duplicate triplets.


The idea is the same as the following topic, just pay attention to de-emphasis. The same deduplication problem also occurs in 4sum.


public class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        if(nums.length < 3 || nums == null){
            return new ArrayList<List<Integer>>();
        }
        // before using two pointer, we should sort the array in order to achieve higher efficiency
        Arrays.sort(nums);
        ArrayList<List<Integer>> return_list = new ArrayList<List<Integer>>();
        for(int i=0; i<nums.length-2; i++){
            if(i==0 || (i>0 && nums[i]!=nums[i-1])){
                int lp = i+1;
                int hp = nums.length-1;
                int target = 0 - nums[i];
                while(lp<hp){
                    if(nums[lp]+nums[hp] == target){
                        return_list.add(Arrays.asList(nums[i],nums[lp],nums[hp]));
                        while(lp<hp && nums[lp+1]==nums[lp]){
                            lp++;
                        }
                        while(lp<hp && nums[hp-1]==nums[hp]){
                            hp--;
                        }
                        lp++;
                        hp--;
                    }else if(nums[lp]+nums[hp]<target){
                        lp++;
                    }else{
                        hp--;
                    }
                }
            }
        }
        return return_list;
    }
}


16. 3Sum Closest

Given an array nums of n integers and an integer target, find three integers in nums such that the sum is closest to target. Return the sum of the three integers. You may assume that each input would have exactly one solution.

Example:
Given array nums = [-1, 2, 1, -4], and target = 1.

The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).


Two points: 1) Remember that the distance is an absolute value; 2) The moving standard of two pointers must first compare the size and sort first.

class Solution {
    public int threeSumClosest(int[] nums, int target) {
        // Traverse the first pointer, the other two pointers follow the general two pointers principle
        int n = nums.length;
        Arrays.sort(nums);
        int diff = Integer.MAX_VALUE;
        int ans = Integer.MAX_VALUE;
        for (int i = 0; i < n - 2; ++i) {
            int v1 = nums[i];
            int j = i + 1;
            int k = n - 1;
            while (j < k) {
                int sum = v1 + nums[j] + nums[k];
                int curDiff = Math.abs(sum - target);
                if (curDiff < diff) {
                    diff = curDiff;
                    ans = sum
                }
                if (sum > target) {
                    --k;
                } else if (sum < target) {
                    ++j;
                } else {
                    return ans;
                }
            }
        }
        return ans;
    }
}


26. Remove Duplicates from Sorted Array


class Solution {
    public int removeDuplicates(int[] nums) {
        if (nums == null || nums.length < 2) {
            return (nums == null ? 0 : nums.length);
        }
        
        int n = nums.length;
        int writeIndex = 1;
        
        for (int i = 1; i < n; ++i) {
            if (nums[i] != nums[writeIndex - 1]) {
                nums[writeIndex] = nums[i];
                ++writeIndex;
            }
        }
        return writeIndex;
    }
}


19. Remove Nth Node From End of List

Note: The dummy node can only handle the case where [1] deletes the first one.

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(-1);
        dummy.next = head;
        ListNode fast = head;
        ListNode slow = dummy;
        for (int i = 1; i < n; ++i) {
            fast = fast.next;
        }
        
        // let the snow to be the nth's prev
        while (fast.next != null) {
            fast = fast.next;
            slow = slow.next;
        }
        
        ListNode target = slow.next;
        slow.next = target.next;
        target.next = null;
        return dummy.next;
    }
}



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324686300&siteId=291194637