Вопрос: Учитывая массив A и цель T, проверьте, существует ли пара в A, сумма которой равна T.
Если вы начинаете подготовку к собеседованию, обычно это первое, с чем вы сталкиваетесь.
Давайте разберемся с этим. Что этот вопрос просит нас сделать?
- Нам дан массив, этот массив может быть отсортирован или несортирован. Пусть[] = [2,5,1,6,8,3,4,7]
- Нам дали цель
- Мы должны вернуть проверку, существует ли пара, сумма которой равна t, т.Е. Пусть x и y будут двумя элементами в таком, что. Мы должны найти эти два элемента.
Наивный/грубый силовой подход: Подход грубой силы заключался бы в поиске каждой пары x и y, которая суммировалась бы с целью T:
public class Solution {
//brute force O(n^2) time O(1) space
public int[] twoSum(int[] nums,int target){
for(int i=0;iЭто сгенерирует все возможные пары и вернет первую пару, которая соответствует условию, теперь давайте рассмотрим случай, когда give массив является
A = [1,2,3,4,5,6,7,8] Target = 15
В этом случае все возможные комбинации из [1,2],[1,3],[1,4],[1,5]..[7,8] будет сгенерирован.
Улучшение: Давайте подумаем о том, что у нас есть в нашем распоряжении, как мы можем манипулировать массивом таким образом, чтобы он сокращал время в предыдущем наихудшем сценарии, наихудший случай возникает, когда нам приходится искать весь массив, а результат находится в последнем ie [7,8]?
- Сортировка и два указателя: если мы отсортируем массив A, то A станет [1,2,3,4,5,6,7,8]. Как мы можем использовать это в наших интересах? давайте назначим два указателя, начало и конец. &.длина-1 ; здесь мы наблюдаем, что если
- числа[начало] + числа[конец], мы пришли к решению.
- числа [начало] + числа [конец] > цель, у нас слишком много большего числа, поэтому уменьшите конец.
- числа [начало] + числа[конец] < цель, у нас слишком мало меньшего числа, поэтому увеличьте начало. Но здесь мы сталкиваемся с предостережением, так как ожидается, что мы вернем индексы элементов в массиве. Для этого мы делаем:
- найдите начальный и конечный элементы в массиве.
int[] nums2 = Arrays.copyOf(nums, nums.length);
Arrays.sort(nums2);
int a = 0, b = 0;
int start = 0, end = nums2.length-1;
//find two nums
while(start target)
end--;
else{
a = nums2[start]; b = nums2[end];
break;
}
}
//find the index of two numbers
int[] res = new int[2];
for(int i = 0; i < nums.length; i++){
if(nums[i] == a){
res[0] = i;
break;
}
}
if(a != b){
for(int i = 0; i < nums.length; i++){
if(nums[i] == b){
res[1] = i;
break;
}
}
} else{
for(int i = 0; i < nums.length; i++){
if(nums[i] == b && i != res[0]){
res[1] = i;
break;
}
}
}
return res;
}
На этом этапе интервьюер должен быть доволен тем, что вы приближаетесь но он спросит: “Можем ли мы сделать лучше?” И да, мы можем.
- Хэш-карта: Хэш-карта хранит пары, мы используем это свойство для хранения индекса и суммы. Мы храним целевое число[i] в качестве ключа, а индекс i – в качестве значения. Давайте пройдемся по нему: для массива [2,5,1,6,8,3,4,7] и хранятся пары ключ-значение:
2 > 15-2 = 13 <13,0> 5 > 15-5 = 10 <10,1> 1 > 15-1 = 14 <14,2> 6 > 15-6 = 9 < 6,3> 8 > 15-8 = 7 < 7,4> 3 > 15-3 = 12 <12,5> 4 > 15-4 = 11 <11,6>
7 > теперь вот где происходит волшебство, так как в индексе 4, элемент 8, мы сохранили <7,4> в HashMap, это означает, что нам это нужно, и мы видели в позиции 4. а это значит, что мы нашли решение. верните текущий индекс 7, т.е. 7, и индекс 8, т.е. 4.
Mapmap = new HashMap<>(); int[] res = new int[]{-1,-1}; for(int i=0;i
Надеюсь, вам понравилась поездка. Ссылка на Github: https://github.com/AKHILP96/Data-Structures-and-Algorithms/blob/master/problems/TwoSum.java
Оригинал: “https://dev.to/akhilpokle/2-ways-to-two-sum-2dbh”