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
- First we sort the array.
- 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.
- 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:
- Array to re-issue Remove duplicates in an array
- Window Sum sliding window problem
- The difference between two numbers problem Two Difference
- List midpoint issues Middle of Linked List
- 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 = 2
words, 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|,4
when 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
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:
- If nums [j] - nums [i] == | target |, then find the answer
- Otherwise, we will try to move i, i make a move to the right => i ++
- 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 - 1
tuple 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
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:
- Median data stream http://www.lintcode.com/problem/data-stream-median/
- K maximum data flow item http://www.lintcode.com/problem/top-k-largest-numbers-ii/
- 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
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
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.