Leetcode 167 Two Sum II - Input Array Is Sorted

Soru

Given a 1-indexed array of integers numbers that is already sorted in non-decreasing order, find two numbers such that they add up to a specific target number. Let these two numbers be numbers[index1] and numbers[index2] where 1 <= index1 < index2 <= numbers.length.

Return the indices of the two numbers, index1 and index2, added by one as an integer array [index1, index2] of length 2.

The tests are generated such that there is exactly one solution. You may not use the same element twice.

Örnek 1

Input: numbers = [2,7,11,15], target = 9
Output: [1,2]
Explanation: The sum of 2 and 7 is 9. Therefore, index1 = 1, index2 = 2. We return [1, 2].

Örnek 2

Input: numbers = [2,3,4], target = 6
Output: [1,3]
Explanation: The sum of 2 and 4 is 6. Therefore index1 = 1, index2 = 3. We return [1, 3].

Örnek 3

Input: numbers = [-1,0], target = -1
Output: [1,2]
Explanation: The sum of -1 and 0 is -1. Therefore index1 = 1, index2 = 2. We return [1, 2].

Çözüm

  • LeetCode’daki “167. Two Sum II - Input Array Is Sorted” sorusu, sıralı bir tam sayı dizisinde verilen bir hedef sayıya eşit olacak şekilde iki sayının toplamını bulmanızı ister.

  • Ancak bu versiyonda, sıfırdan başlamayan 1’den başlayan dizinleri döndürmeniz istenir.

  • Girdi: Sıralı bir tam sayı dizisi numbers ve bir hedef sayı target.

  • Çıktı: İki sayının toplamı hedef sayıya eşit olduğunda, bu iki sayının dizindeki konumlarını (1’den başlayarak) bir liste olarak döndürün.

  • Bu problem için etkili bir çözüm yöntemi, iki işaretçi kullanmaktır. Bu yaklaşımda, bir işaretçi dizinin başında (left) ve diğer işaretçi dizinin sonunda (right) başlar. İki işaretçi birbirine doğru hareket ederken, işaret ettikleri elemanların toplamını hedef sayıyla karşılaştırır.

  • İşaretçilerin İnitialize Edilmesi: left işaretçisi dizinin başında, right işaretçisi ise dizinin sonunda başlar.

  • Toplamın Karşılaştırılması: İşaretçilerin gösterdiği iki değerin toplamı current_sum hesaplanır.

  • Koşul Kontrolü: Eğer current_sum hedef sayıya (target) eşitse, 1’den başlayarak indeksleri döndürülür. Eğer current_sum hedef sayıdan küçükse, left işaretçisi bir arttırılarak toplamın büyütülmesi sağlanır. Eğer current_sum hedef sayıdan büyükse, right işaretçisi bir azaltılarak toplamın küçültülmesi sağlanır.

  • Döngü Bitişi: left işaretçisi right işaretçisinden küçük olduğu sürece döngü devam eder.

  • Örneğin [1,2,7,11,15] 9 elde etmek isteyelim.İlk işaretçi 1 de ikinci işaretçi 15 te başlasın.

  • 1+15 = 16 hedefimizden büyük o zaman en sağdaki işaretçiyi 1 sola kaydırırız.

  • 1+11 = 12 hedefimizden büyük o zaman en sağdaki işaretçiyi 1 sola kaydırırız.

  • 1+7 = 8 hedefimizden küçük o zaman en soldaki işaretçiyi 1 sağa kaydırırız.

  • 2+7 = 9 hedefimize ulaştık.

Code

    def twoSum(self, numbers: List[int], target: int) -> List[int]:
        l,r = 0, len(numbers) - 1
        
        while l<r:
            curSum = numbers[l] + numbers[r]
            
            if curSum > target:
                r-=1
            elif curSum < target:
                l+=1
            else:
                return[l+1,r+1]
        return []

Complexity

  • Time complexity(Zaman Karmaşıklığı): O(n), burada n dizinin uzunluğudur. Dizi en fazla bir kez taranır.
  • Space complexity(Alan Karmaşıklığı): O(1), çünkü ekstra bir alan kullanılmaz ve yalnızca iki işaretçi ile çözüm sağlanır.