1. 程式人生 > >python陣列雙指標演算法

python陣列雙指標演算法

1.求和問題(LeetCode 2sum & 3sum & 4sum)

1 Two Sum

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.
 

a.傳統方法,暴力O(n**2)

def sum_2(nums, target):
    length=len(nums)
    for i in range(0, len(nums)-1):
        for j in range(i+1, l):
            if nums[i]+nums[j]==target:
                return[i,j]

b.排序O(logn)

def sum_2(alist, target):
    alist.sort()
    length=len(alist)
    i=0
    j=length-1
    while i<j:
        s=alist[i]+alist[j]
        if s<target:
            i+=1
        elif s>target:
            j-=1
        else:
            return [alist[i], alist[j]]
        

c.雜湊表結構

class Solution:
    def twoSum(self, nums, target):
        map = {}
        for i in range(len(nums)):
            if nums[i] not in map:
                map[target - nums[i]] = i
            else:
                return map[nums[i]], i

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.
Example:
Given array nums = [-1, 0, 1, 2, -1, -4],
A solution set is:
[
  [-1, 0, 1],
  [-1, -1, 2]

]
 

def sum_3(nums, target):
    nums.sort()
    result=[]
    if len(nums)<3:
        return result
    length=len(nums)
    for i in range(0, length):
        j=i+1
        k=length-1
        if i>0 and nums[i]==nums[i-1]:
            continue
        while j<k:
            sum=nums[i]+nums[j]+nums[k]
            if sum==target:
                result.append((nums[i], nums[j], nums[k]))
                k-=1
                j+=1
                while nums[j]==nums[j-1] and nums[k]==nums[k+1] and j<k:
                    j+=1
                    k-=-1
            elif sum>target:
                k-=1
                while nums[k]==nums[k+1]:
                    k-=1
            else:
                j+=1
                while nums[j]==nums[j-1]:
                    j-=1
    return list(set(result))

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).
 

class Solution(object):
    def threeSumClosest(self, nums, target):
        length=len(nums)
        Min=2147483647
        nums.sort()
        for i in range(length-2):
            if i>0 and nums[i]==nums[i-1]:
                continue
            j=i+1
            k=length-1
            while j<k:
                sum=nums[i]+nums[j]+nums[k]
                if abs(sum-target)<abs(Min):
                    Min=sum-target
                if sum==target:
                    return target
                elif sum>target:
                    k-=1
                else:
                    j+=1
        return Min+target

18. 4Sum

Given an array nums of n integers and an integer target, are there elements a, b, c, and d in nums such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.
Note:
The solution set must not contain duplicate quadruplets.
Example:
Given array nums = [1, 0, -1, 0, -2, 2], and target = 0.
A solution set is:
[
  [-1,  0, 0, 1],
  [-2, -1, 1, 2],
  [-2,  0, 0, 2]

]
 

def sum_4(nums, target):
    nums.sort()
    res=[]
    length=len(nums)
    for i in range(0, length):
        if i>0 and nums[i]==nums[i-1]:
            continue
        for j in range(i+1, length):
            if j>i+1 and nums[j]==nums[j-1]:
                continue
            start=j+1
            end=length-1
            while start<end:
                sum=nums[i]+nums[j]+nums[start]+nums[end]
                if sum>target:
                    end-=1
                elif sum<target:
                    start+=1
                else:
                    res.append((nums[i], nums[j], nums[start], nums[end]))
                    start+=1
                    end-=1
                    while start<end and nums[start]==nums[start-1]:
                        start+=1
                    while start<end and nums[end]==nums[end+1]:
                        end-=1
    return res

2.元素交換(LeetCode Remove Duplicates from Sorted Array & Remove Element)

26. Remove Duplicates from Sorted Array

Given a sorted array nums, remove the duplicates in-place such that each element appear only once and return the new length.

Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.

Given nums = [0,0,1,1,1,2,2,3,3,4],

Your function should return length = 5,with the first five elements of nums being modified to 0, 1, 2, 3, 4
respectively.It doesn't matter what values are set beyond the returned length.
 

class Solution:
    def removeDuplicates(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if len(nums) <=1:
            return len(nums)
        it=0
        for i in range(1,len(nums)):
            if nums[i] != nums[it]:
                it+=1
                nums[it]=nums[i]
        return it + 1

80. Remove Duplicates from Sorted Array II

Given a sorted array nums, remove the duplicates in-place such that duplicates appeared at most twice and return the new length.

Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.
 

class Solution:
    def removeDuplicates(self, nums):
        l = len(nums)
        if l < 2:
            return l
        i = 1
        numlen = 1
        f = 1
        while i < l:
            if nums[i] != nums[numlen-1]:
                nums[numlen] = nums[i]
                numlen += 1
                f = 1
            elif nums[i] == nums[numlen-1] and f:
                nums[numlen] = nums[i]
                numlen += 1
                f = 0                
            i += 1
        return numlen

27. Remove Element

Given an array nums and a value val, remove all instances of that value in-place and return the new length.

Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.

The order of elements can be changed. It doesn't matter what you leave beyond the new length.

Given nums = [0,1,2,2,3,0,4,2], val = 2,Your function should return length = 5, with the first five elements of
nums containing 0, 1, 3, 0, and 4. Note that the order of those five elements can be arbitrary.It doesn't matter what values are set beyond the returned length.

//雙指標
class Solution:
    def removeElement(self, nums, val):
        if not nums:
            return 0
        l = len(nums)
        i = 0
        j = l - 1
        while i <= j:
            if nums[i] == val:
                while nums[j] == val and j > i:
                    j -= 1
                nums[i] = nums[j]
                j -= 1
                if j <= i:
                    break
            i += 1
        return j + 1


//暴力
class Solution(object):
    def removeElement(self, nums, val):
        """
        :type nums: List[int]
        :type val: int
        :rtype: int
        """
        slow = -1
        for i in xrange(0, len(nums)):
            if nums[i] != val:
                slow += 1
                nums[slow] = nums[i]
        return slow + 1

283. Move Zeroes

Given an array nums, write a function to move all 0's to the end of it while maintaining the relative order of the non-zero elements.
 

class Solution:
    def moveZeroes(self, nums):
        n = 0
        for i in range(len(nums)):
            if nums[i]:
                if n != i:
                    nums[n] = nums[i]
                    nums[i] = 0
                n += 1

3.滑動視窗(LeetCode Subarray Product Less Than K & Container With Most Water)

713. Subarray Product Less Than K

Your are given an array of positive integers nums.

Count and print the number of (contiguous) subarrays where the product of all the elements in the subarray is less than k.

class Solution:
    def numSubarrayProductLessThanK(self, nums, k):
        cn = 0
        if k <= 1:
            return cn        
        start = 0
        end = 0
        cn = 0
        prod = 1
        
        while end < len(nums):
            prod *= nums[end]
            end += 1
            while prod >=k:
                prod /= nums[start]
                start += 1
            cn += end -start
        return cn

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.

Note: You may not slant the container and n is at least 2.
 

class Solution(object):
    def maxArea(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        l=len(height)
        max_v=0
        i, j=0, l-1
        while i<j:
            x, y=height[i], height[j]
            h=min(x, y)
            vol=h*(j-i)
            if vol>max_v:
                max_v=vol
            while height[i]<h and i<j:
                i+=1
            while height[j]<h and i<j:
                j-=1
        return max_v

42. Trapping Rain Water

Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.

The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped. Thanks Marcosfor contributing this image!

class Solution(object):
    def trap(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        if len(height)==0:
            return 0
        left, right=0, len(height)-1
        max_left=height[left]
        max_right=height[right]
        water=0
        
        while left<right:
            if height[left]<height[right]:
                max_left=max(max_left, height[left])
                water+=max_left-height[left]
                left+=1
            else:
                max_right=max(max_right, height[right])
                water+=max_right-height[right]
                right-=1
        return water
        
        

41. First Missing Positive
Given an unsorted integer array, find the smallest missing positive integer.

Example 1:

Input: [1,2,0]
Output: 3
Example 2:

Input: [3,4,-1,1]
Output: 2
Note:

Your algorithm should run in O(n) time and uses constant extra space.
 

class Solution(object):
    def firstMissingPositive(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        a=1
        while True:
            if a not in nums:
                return a
            else:
                a+=1

229. Majority Element II
Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times.

Note: The algorithm should run in linear time and in O(1) space.
 

from collections import Counter
return [k for k,v in Counter(nums).items() if v > len(nums)//3]

238. Product of Array Except Self
Given an array nums of n integers where n > 1,  return an array output such that output[i] is equal to the product of all the elements of nums except nums[i].

Note: Please solve it without division and in O(n).

Follow up:
Could you solve it with constant space complexity? (The output array does not count as extra space for the purpose of space complexity analysis.)
 

class Solution:
    def productExceptSelf(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        output = [1]
        prod = 1
        for num in nums[:-1]:
            prod *= num
            output.append(prod)
        
        prod = 1
        for i in range(len(nums), 0, -1):
            output[i-1] *= prod
            prod *= nums[i-1]
        
        return output