Je lisais le Modèle de recherche binaire II dans leetcode :
Il est utilisé pour rechercher un élément ou une condition qui nécessite d'accéder à l'index courant et à l'index de son voisin droit immédiat dans le tableau.
In [4]: nums = list(range(100)) In [5]: binarySearch(nums, 55) Out[5]: 55 In [6]: binarySearch(nums, 101) Out[6]: -1 In [7]: binarySearch(nums, 38) Out[7]: 38
Il me semble que la condition supplémentaire et nums [left] == target n'est pas nécessaire.
Lors du changement:
def binarySearch(nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
if len(nums) == 0:
return -1
left, right = 0, len(nums)
while left < right:
mid = (left + right) // 2
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1
else:
right = mid
# Post-processing:
# End Condition: left == right
if left != len(nums):
return left
return -1
à seulement:
if left != len(nums):
... cela fonctionne parfaitement:
if left != len(nums) and nums[left] == target:
Tests:
def binarySearch(nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
if len(nums) == 0:
return -1
left, right = 0, len(nums)
while left < right:
mid = (left + right) // 2
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1
else:
right = mid
# Post-processing:
# End Condition: left == right
if left != len(nums) and nums[left] == target:
return left
return -1
Quelle est la raison pour laquelle nums [left] == target devrait être ajouté?
Le résumé du Leetcode sur le modèle (pour référence si vous ne pouviez pas ouvrir son lien):
Attributs clés:
- Une manière avancée de mettre en œuvre la recherche binaire.
- La condition de recherche doit accéder au voisin droit immédiat de l'élément
- Utilisez le voisin droit de l'élément pour déterminer si la condition est remplie et décider s'il faut aller à gauche ou à droite
- Gurantees [sic] L'espace de recherche est d'au moins 2 à chaque étape
- Post-traitement requis. La boucle / récursivité se termine lorsqu'il vous reste 1 élément. Il faut évaluer si l'élément restant répond aux condition.
Syntaxe distinctive:
- Condition initiale:
left = 0, right = length- Résiliation:
left == right- Recherche à gauche:
right = mid- Recherche à droite:
gauche = milieu + 1
3 Réponses :
Test avec nums = [9] et binarySearch (nums, 2) . Si je comprends bien le code, binary_search renverra 0 comme "index" de l'élément trouvé.
Vous avez besoin de la dernière condition pour vous assurer que vous a effectivement trouvé l'élément cible .
Sinon, vous cherchez simplement un index pour l'élément le plus proche de la cible dans le tableau.
Encore un exemple: p>
IN nums = [1, 3, 4] IN binary_search(nums, 2) OUT 2 /* When 2 isn't in the array */
l'exemple ne peut pas être une indication formelle de la nécessité de ce contrôle (et en particulier de cette chose "à peu près")
Contrairement à la version canonique de la recherche binaire où la boucle se termine dès que lo> hi est rencontré, dans ce cas, la boucle se termine lorsque lo == hi . Mais comme l'élément nums [lo] (qui est aussi nums [hi] ) doit également être inspecté, la vérification supplémentaire est ajoutée après la boucle.
Il est garanti que la boucle se termine uniquement et uniquement lorsque lo == hi , car le déplacement vers la gauche inclut l'élément mid dans la recherche future ( else: right = mid ) en version canonique, l'élément mid est exclu de la recherche future dans les deux cas
Tout d'abord, lorsque vous changez si à gauche! = len (nums) et nums [left] == target: en si left! = len (nums): code >
cela semble fonctionner correctement car vos tests sont effectués avec nums = list (range (100)) qui génère la séquence d'entiers 0, 1, 2,. .., 99 , en tant que tel, chaque index de nums est le même que son élément, c'est-à-dire nums [i] == i . Sans nums [left] == target , vous retournez en fait l'index le plus proche de l'index de votre élément target , et puisque avec votre test chaque index coïncide avec son élément alors il semble donner des résultats corrects, mais c'est faux . La nums [left] == target est la condition de fin qui garantit que vous avez effectivement trouvé votre élément target dans nums .
Test avec
nums = [9]etbinarySearch (nums, 2). Vous avez besoin de la dernière condition pour vous assurer que vous avez réellement trouvé l'élément cible.Cela fonctionne
In [19]: binarySearch (list (range (10)), 2) Out [19]: 2 In [20]: binarySearch (list (range (9)), 2) Out [20]: 2@ChrisHappyDésolé, la liste ne doit pas être
0, 1, 2, 3, 4, 5, 6, 7, 8, 9. Ce devrait être simplement9. Reformulé, l'algorithme binary_search échoue lorsque l'élément n'est pas dans le tableau et il n'est pas plus grand que le plus grand élément et pas plus petit que le plus petit élément.Donc, pourrait être simplement supprimer la ligne `if left! = Len (nums) and nums [left] == target:`