程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Binary search Python bisect built-in module

編輯:Python

Two points search The first lesson

  • The first part Clear up bisect modular
    • example
    • summary :
  • *35. Search insert location
  • 2089. Find the target subscript after array sorting
  • Python bisect Built-in module
  • Python bisect Source code

The first part Clear up bisect modular

* Module only for [ Ascending list ]

i, j = 0, len(a) # *[0, len(a)) Half open and half closed interval 
''' bisect_left Left insertion position '''
while i < j:
mid = i + j >> 1
if a[mid] < target: i = mid + 1 # Increasing < i The relationship between the three , First judge less than 
else: j = mid
return i
''' bisect_right Right insertion position '''
while i < j:
mid = i + j >> 1
if a[mid] > target: j = mid # First judge whether it is greater than 
else: i = mid + 1
return i

example

from bisect import *
a = [1, 2, 6, 6, 6, 8] # Ascending 
bisect_left(a, 4) # Insertion position 2, The corresponding element 6 
bisect(a, 4) # ditto 
bisect_left(a, 6) # ditto 
bisect(a, 6) # Insertion position 5, The corresponding element 8 

summary :

Goals exist , Left is the leftmost x; Right is the rightmost x My right neighbor ;
The goal doesn't exist , The left and right are the same , Are element positions larger than the target .

  1. Note that * Insertion position
  2. Only aim at * Ascending .
  3. target non-existent , Return the position of the right neighbor ; There is bisect_left Return to the first target location , bisect_right
    Returns the position of the right neighbor of the last target .
  4. The relationship between the three :bisect_left、<、i ;bisect_right、>、j
  5. Conditions while i < j: return i = j

*35. Search insert location

* distinguish : Insert position and target position

class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
return bisect_left(nums, target)
# Right lookup is different when the target exists , There are no repeating elements , Right insertion position - 1 = Left insertion position 
i = bisect_right(nums, target)
return i-1 if nums[i-1] == target else i

2089. Find the target subscript after array sorting

class Solution:
def targetIndices(self, nums: List[int], target: int) -> List[int]:
nums.sort()
i = bisect_left(nums, target)
j = bisect_right(nums, target)
return list(range(i, j))

Python bisect Built-in module

file
Source code : Lib/bisect.py
bisect, It's the realization of Two points (bisection) Algorithm Module , The sequence order can be kept unchanged Binary search and insert .

import bisect
dir(bisect)
bisect.bisect_left(a, x, lo=0, hi=len(a), *, key=None)

If x Already in a In existence , Then the insertion point will be before the existing element ( On the left ).

The left half all(val < x for val in a[lo : i])
Right half all(val >= x for val in a[i : hi])

bisect.bisect_right(a, x, lo=0, hi=len(a), *, key=None)
bisect.bisect(a, x, lo=0, hi=len(a), *, key=None)

The insertion point returned is a Element already exists in x The right side of the .

The left half all(val <= x for val in a[lo : i])
Right half all(val > x for val in a[i : hi])

bisect.insort_left(a, x, lo=0, hi=len(a), *, key=None)

Place... In sorted order x Insert into a in .

This function first runs bisect_left() To locate an insertion point . then , It will be a Up operation insert() Method to insert in the correct position x To maintain the sort order .

bisect.insort_right(a, x, lo=0, hi=len(a), *, key=None)
bisect.insort(a, x, lo=0, hi=len(a), *, key=None)

hold x Insert into a Element already exists in x The right side of the .

stay a Up operation insert() Method to insert in the correct position x To maintain the sort order .

To support inserting records in a table, the key function (if any) is applied to x for the search step but not for the insertion step.

key specifies a key function of one argument that is used to extract a comparison key from each element in the array. To support searching complex records, the key function is not applied to the x value.

If key is None, the elements are compared directly with no intervening function call.

Dichotomy is very efficient for searching a range of values . For positioning specific values , The performance of the dictionary is better .

Be careful , Use bisect Before the module method , The operation object is required to be Ordered sequence ( l 、 drop ).
In the sequence a Find the appropriate element in the dichotomy x Insertion position , Guarantee a Still an ordered sequence .
lo and hi Is an optional parameter , Define the search range respectively / Returns the of the index Upper and lower limits , By default, the default is for Whole Sequence lookup .
therefore , Returned location index Also known as “ The insertion point ”, Set it to i, Then the sequence a It can be divided into two parts , The slice represents the left side a[lo, i) And the right side a[i, hi] .

Python bisect Source code

"""Bisection algorithms."""
def insort_right(a, x, lo=0, hi=None, *, key=None):
"""Insert item x in list a, and keep it sorted assuming a is sorted. If x is already in a, insert it to the right of the rightmost x. Optional args lo (default 0) and hi (default len(a)) bound the slice of a to be searched. """
if key is None: lo = bisect_right(a, x, lo, hi)
else: lo = bisect_right(a, key(x), lo, hi, key=key)
a.insert(lo, x)
def bisect_right(a, x, lo=0, hi=None, *, key=None):
"""Return the index where to insert item x in list a, assuming a is sorted. The return value i is such that all e in a[:i] have e <= x, and all e in a[i:] have e > x. So if x already appears in the list, a.insert(i, x) will insert just after the rightmost x already there. Optional args lo (default 0) and hi (default len(a)) bound the slice of a to be searched. """
if lo < 0: raise ValueError('lo must be non-negative')
if hi is None: hi = len(a)
# Note, the comparison uses ">" to match the
# __lt__() logic in list.sort() and in heapq.
if key is None:
while lo < hi:
mid = (lo + hi) // 2
if a[mid] > x: hi = mid
else: lo = mid + 1
else:
while lo < hi:
mid = (lo + hi) // 2
if key(a[mid]) > x: hi = mid
else: lo = mid + 1
return lo
def insort_left(a, x, lo=0, hi=None, *, key=None):
"""Insert item x in list a, and keep it sorted assuming a is sorted. If x is already in a, insert it to the left of the leftmost x. Optional args lo (default 0) and hi (default len(a)) bound the slice of a to be searched. """
if key is None: lo = bisect_left(a, x, lo, hi)
else: lo = bisect_left(a, key(x), lo, hi, key=key)
a.insert(lo, x)
def bisect_left(a, x, lo=0, hi=None, *, key=None):
"""Return the index where to insert item x in list a, assuming a is sorted. The return value i is such that all e in a[:i] have e < x, and all e in a[i:] have e >= x. So if x already appears in the list, a.insert(i, x) will insert just before the leftmost x already there. Optional args lo (default 0) and hi (default len(a)) bound the slice of a to be searched. """
if lo < 0: raise ValueError('lo must be non-negative')
if hi is None: hi = len(a)
# Note, the comparison uses "<" to match the
# __lt__() logic in list.sort() and in heapq.
if key is None:
while lo < hi:
mid = (lo + hi) // 2
if a[mid] < x: lo = mid + 1
else: hi = mid
else:
while lo < hi:
mid = (lo + hi) // 2
if key(a[mid]) < x: lo = mid + 1
else: hi = mid
return lo
# Overwrite above definitions with a fast C implementation
try:
from _bisect import *
except ImportError:
pass
# Create aliases
bisect = bisect_right
insort = insort_right

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved