Double pointer arithmetic template and some of the topics

What is with the double pointer? What is facing a double pointer?
Speed ​​pointer arithmetic on two numbers and Two Sum chain - double pointer originator title
Quick sort & merge sort

 

• facing the same direction double pointer double pointer
• Almost all variants • Partition Two Sum
• Quick Select • • divided into two parts divided into three parts
• something you have not heard of (but examination of the interview) sorting algorithm

 

 

A typical problem is facing the double pointer string flipping problem.

 

Python:

"""
@param s: a list of characters
"""
def reverse(s): left, right = 0, len(s)-1 while left < right: s[left], s[right] = s[right], s[left] left += 1 right -= 1 

Another double pointer classic exercises, is a palindrome string of judgment. To a string, the string is determined string is not a palindrome.

We can use a double pointer arithmetic easily solved:

Python:

def isPalindrome(s):
    i, j = 0, len(s)-1 while i < j: if s[i] != s[j]: return False i += 1 j -= 1 return True 

 Double pointer originator: two numbers

Title Description

To an array of integers, find the two numbers and make them equal to a given number of target.
Return these two numbers.

Python:

class Solution:
    def twoSum(self, numbers, target): numbers.sort() L, R = 0, len(numbers)-1 while L < R: if numbers[L]+numbers[R] == target: return (numbers[L], numbers[R]) if numbers[L]+numbers[R] < target: L += 1 else: R -= 1 return None 
  1. First we sort the array.
  2. Two right and left pointers beginning with (L, R):
    • If numbers [L] + numbers [R] == target, description found, returns the corresponding number.
    • If numbers [L] + numbers [R] <target, this time right pointer L, and the only way to make available greater.
    • Conversely that R left.
  3. L and R meet yet to find no solution will be described.

 

With the double pointer

With the issue of double pointer, it refers to the two pointers are starting from scratch, moving in the same direction. We come to a preliminary understanding with the two-pointer by the following five topics:

  1. Array to re-issue Remove duplicates in an array
  2. Window Sum sliding window problem
  3. The difference between two numbers problem Two Difference
  4. List midpoint issues Middle of Linked List
  5. Belt loop chain issues Linked List Cycle

Problem Description

After you give an array, it requires the removal of repetitive elements will not be repeated preceding array elements moved, and returns the number of elements is not repeated.

LintCode exercises Address: http://www.lintcode.com/problem/remove-duplicate-numbers-in-array/

problem analysis

There are two approaches to this problem, the first approach is easier to think that all the numbers thrown into the hash table, then you can find different integers which. However, this approach would consume extra space O (n-) O (n-) O ( n- ). The interviewer will ask, how not to spend extra space.

At this point we need to use double pointer arithmetic, first sort the array, so those unique integer will be pushed together. Then two pointers, a pointer Some go faster traverse the entire array, a pointer Furthermore, the current does not always point to repeat the last section number. After a quick find different pointers and pointer count slow, this number can be thrown into a position behind the slow pointer, and the pointer to slow ++.

# O(nlogn) time, O(1) extra space
class Solution:
    # @param {int[]} nums an array of integers
    # @return {int} the number of unique integers
    def deduplication(self, nums):
        # Write your code here
        n = len (nums)
        if n == 0:
            return 0
            
        nums.sort()
        result = 1
        for i in range(1, n):
            if nums[i - 1] != nums[i]:
                nums[result] = nums[i]
                result += 1
                
        return result

 

Problem Description

Obtaining an array each of KK K and an array of consecutive integers. As = the nums [1,2,3,4], K = 2words, window sum for the array [3,5,7].
http://www.lintcode.com/problem/window-sum/

problem analysis

This question and there is no difficulty, but if you are too Violence user O (the n-* k) O (the n-* k) O ( the n- * k ) algorithm to do is not right. Such as the current A window is an |1,2|,3,4. Then when the window is moved from left to right 1,|2,3|,4when the entire window and an integer of 3 is increased, reducing the 1. It is only necessary to simulate the whole process of the sliding window, into an integer a to change. This is the sliding window problem.

class Solution:
    # @param nums {int[]} a list of integers
    # @param k {int} size of window
    # @return {int[]} the sum of element inside the window at each moving
    def winSum(self, nums, k):
        # Write your code here
        n = len (nums)
        if n < k or k <= 0:
            return []
        sums = [0] * (n - k + 1)
        for i in range(k):
            sums[0] += nums[i];

        for i in range(1, n - k + 1):
            sums[i] = sums[i - 1] - nums[i - 1] + nums[i + k - 1]

        return sums

 

The difference between the two numbers problem

610. The number and the two - is equal to the target value

Chinese
English

Given an array of integers, find the two numbers is equal to the target value. index1 must be less than index2. Note that the return of index1 and index2 is not 0-based.

Sample

Example 1:

输入: nums = [2, 7, 15, 24], target = 5 
输出: [1, 2] 
解释:
(7 - 2 = 5)

Example 2:

输入: nums = [1, 1], target = 0
输出: [1, 2] 
解释:
(1 - 1 = 0)

Precautions

To ensure that there is only one answer.

problem analysis

Follow up as a problem and the two numbers, two numbers and in a bad interview question was asked later, the difference between two numbers is a frequent occurrence.
We can first try and the number of two methods and found that did not work, because even in the array is already sorted premise, nums [i] - nums [ j] the relationship between the target and we can not decide eliminated nums [i] or nums [j].

So we try to go forward with two hands instead of each other halfway, the i pointer to nums [i] when, j pointer to first make nums [j] - nums [i]> = | target | of subscript j:

  1. If nums [j] - nums [i] == | target |, then find the answer
  2. Otherwise, we will try to move i, i make a move to the right => i ++
  3. J At this point we also will move to the right, until nums [j] - nums [i]> = | target |

We can know that because of j move will not start from scratch, but has been increasing move down, so this time, two cycles between i and j is not a multiplicative relationship but superimposed relationship.

Python:

nums.sort()
target = abs(target)

j = 1
for i in range(len(nums)):
    while j < len(nums) and nums[j]-nums[i] < target: j += 1 if nums[j]-nums[i] == target: # 找到答案 

 

class Solution:
    """
    @param nums: an array of Integer
    @param target: an integer
    @return: [index1 + 1, index2 + 1] (index1 < index2)
    """
    def twoSum7(self, nums, target):
        # write your code here
        target = abs(target)
        nums2 = [(n, i) for i,n in enumerate(nums)]
        nums2.sort(key=lambda x: x[0])
        result = []
        j = 1
        for i in range(len(nums2)):
            while j < len(nums2) and nums2[j][0]-nums2[i][0] < target:
                j += 1
            if nums2[j][0]-nums2[i][0] == target:
                if i != j:
                    result = (nums2[i][1]+1, nums2[j][1]+1)
                    break
        if result[0] > result[1]:                        
            return [result[1], result[0]]
        return result

Similar problems

G family of a similar question: How many find an array of tuples, their squared difference <target (target is a positive integer).
We can put a similar method to solve, first squaring each of the array, then the question becomes how much of the difference between the two numbers <target.
Then go over the top of this process, when find a pair nums [j] - when nums [i]> = target, they found the equivalent of one breath:

nums[i + 1] - nums[i]
nums[i + 2] - nums[i]
...
nums[j - 1] - nums[i]

A total j - i - 1tuple to meet the requirements. The accumulated count, then move to the position i + 1 of.

 

List midpoint problem

Problem Description

Find the midpoint of a linked list

LintCode exercises Address: http://www.lintcode.com/problem/middle-of-linked-list/

228. midpoint of the list

Chinese
English

Find the midpoint of the list.

Sample

Example 1:

输入:  1->2->3
输出: 2	
样例解释: 返回中间节点的值

Sample 2:

输入:  1->2
输出: 1	
样例解释: 如果长度是偶数,则返回中间偏左的节点的值。	

challenge

If the list is a data stream, you can get it without re midpoint traverse the linked list?

"""
Definition of ListNode
class ListNode(object):
    def __init__(self, val, next=None):
        self.val = val
        self.next = next
"""

class Solution:
    """
    @param head: the head of linked list.
    @return: a middle node of the linked list
    """
    def middleNode(self, head):
        # write your code here
        slow, fast = head, head
        while fast and fast.next and fast.next.next:
            slow = slow.next
            fast = fast.next.next
        return slow

Which, fast.next.next conditions can represent two steps forward across.

problem analysis

The question we may feel, WTF so simple there is nothing better to do? You may be thinking:

First look traverse the entire list, find the length L, and then traverse the list to find the node at the position of L / 2 in.

But after you throw this idea, the interviewer will ask you:如果只允许遍历链表一次怎么办?

Follow up can see this is not to let you optimize the time complexity of the algorithm, but strictly limits the number of times you traverse the entire list. You might think that this makes sense to optimize it? In fact it makes sense. Because 遍历一次this scenario, will often encounter in a real engineering environment, that is, we often say 数据流问题(Data Stream Problem).

Data flow problem Data Stream Problem

The so-called data flow problems, that is, you need to design an online system that continuously receive some data, and maintains some of the information that data. For example, this problem is in the data stream to maintain the midpoint where it is. (Midpoint of maintenance means that provides an interface to obtain the midpoint)

Similar problems as well as some of the data stream:

  1. Median data stream http://www.lintcode.com/problem/data-stream-median/
  2. K maximum data flow item http://www.lintcode.com/problem/top-k-largest-numbers-ii/
  3. K-frequency stream data item http://www.lintcode.com/problem/top-k-frequent-words-ii/

The characteristics of such questions is, you 没有机会第二次遍历所有数据. Part of the problem described above will be explained in the "nine chapters algorithm intensive courses" in.

Solve problems with double-pointer list midpoint algorithm

We can use a double pointer arithmetic to solve the problem of the midpoint of the list, more specific, we can call 快慢指针algorithms. The algorithm is as follows:

Python:

slow, fast = head, head.next
while fast != None and fast.next != None:
    slow = slow.next
    fast = fast.next.next

return slow 

A complete reference program

In the above program, we will soon pointer on the second node, slow pointer on the first node, while each loop fast hands to go two steps, slow pointer go one step further. So that when the pointer is fast coming to an end when the slow pointer at the midpoint.

Pointer speed algorithm in the next section of the "belt loop chain", also uses. ======> The wording error-prone, my anticipation can take two steps approach better!

A small exercise

The above code to provide an interface mode, i.e., a design class, supports two functions, one is add(node)to add a node, is a getMiddle()request that intermediate node.

 

102. The belt loop chain

Chinese
English

Given a list, it is determined whether there is a ring.

Sample

```
样例 1:
	输入: 21->10->4->5,  then tail connects to node index 1(value 10).
	输出: true
	
样例 2:
	输入: 21->10->4->5->null
	输出: false

```

challenge

Do not use extra space

"""
Definition of ListNode
class ListNode(object):
    def __init__(self, val, next=None):
        self.val = val
        self.next = next
"""

class Solution:
    """
    @param head: the head of linked list.
    @return: a middle node of the linked list
    """
    def middleNode(self, head):
        # write your code here
        slow, fast = head, head
        while fast and fast.next and fast.next.next:
            slow = slow.next
            fast = fast.next.next
        return slow

 Two classic sorting algorithm

Quick Sort (Quick Sort) and merge sort (Merge Sort) are the two fundamentals point algorithm compulsory interview. Many algorithms interview questions, either directly asked two algorithms, change either of these two algorithms, use either of these two algorithms or implementations of the same idea, either to single out these two algorithms some steps to investigate.

 

Guess you like

Origin www.cnblogs.com/bonelee/p/11789330.html