I felt like doing an algorithm and found this problem on leetcode
Given an array of integers, find two numbers such that they add up to a specific target num
As @Prayer mentioned above, here is the accepted answer.
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] resultarray=new int[2];
for (int i=0;i<nums.length-1;i++){
for(int k=i+1;k<nums.length;k++)
{
if(target==nums[i]+nums[k])
{
resultarray[0]=i;
resultarray[1]=k;
}
}
}
return resultarray;
}
}
Here is the answer using HashMap in java with two passes of the array. Assuming that there are no duplicate elements in the array and there is exactly one solution exists.
import java.util.HashMap;
public class TwoSum {
int[] index = new int[2];
public int[] twoSum(int[] nums, int target)
{
int length = nums.length;
//initialize return values assuming that pair for the given target
//doesn't exist
index[0]=-1;
index[1]=-1;
//sanity check
if(length<1) return index;
HashMap<Integer, Integer> numHash = new HashMap<>(length);
//get the values from array into HashMap assuming that there aren't duplicate values
for(int i=0; i<length;i++)
{
numHash.put(nums[i],i);
}
//check for the value in the array and the difference between target and it. Assume that only
//one such pair exists
for(int i=0;i<length;i++)
{
int val1 = nums[i];
int val2=target-val1;
//make sure that it doesn't return the index of the first number in the pait you are searching for
if( numHash.containsKey(val2) && numHash.get(val2)!=i){
index[0]=i;
index[1] =numHash.get(target-nums[i]);
break;
}
}
return index;
}
}
My solution to this problem would be,
public int[] twoSums(int[] unsortedNum, int target) {
int[] nums = Arrays.copyOf(unsortedNum, unsortedNum.length);
Arrays.sort(nums);
boolean isResultFound = false;
int start = 0;
int end = nums.length-1;
while(!(start > end)) {
if(nums[start]+nums[end] > target){
end--;
} else if (nums[start]+nums[end] < target){
start++;
} else if(nums[start] + nums[end] == target){
isResultFound = true;
break;
}
}
if(isResultFound){
int s = -1;
int e = -1;
for(int i = 0; i< unsortedNum.length; i++){
if(s != -1 && e != -1){
break;
}
if(s == -1 && unsortedNum[i] == nums[start]){
s = i;
} else if(e == -1 && unsortedNum[i] == nums[end]) {
e = i;
}
}
return new int[] {s,e};
}
// for element not found
return new int[]{-1,-1};
}
In the end, if you get -1, -1 as the index then you can say that elements not found which could sum to the target element.
We can do with HashMap and the time complexity would be O(n)
public class ReturnIndicesOfElementsAddToSum {
public static void main(String[] args) {
int[] nums = {2, 7, 11, 15};
int target = 18;
if(!getIndices(nums,target)) {
System.out.println("No such numbers found");
}
}
static boolean getIndices(int[] nums, int target) {
Map<Integer,Integer> indexMap = new HashMap<>();
boolean numFound = false;
for(int i=0;i<nums.length;i++) {
int temp = target - nums[i];
indexMap.put(nums[i], i);
if(indexMap.containsKey(temp)) {
System.out.printf("%d and %d adds upto the target value and indices are %d and %d"
, nums[i], temp, i, indexMap.get(temp));
numFound = true;
}
}
return numFound;
}
}
Using HashMap this is also a solution if complexity for search in HashMap will in order of O(logn) then in worst case the complexity will be O(nlogn)
public int[] twoSum(int[] nums, int target) {
int [] resultIndex = null;
HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
for(int i=0;i<nums.length;i++){
int temp = target - nums[i];
if(map.containsKey(temp)){
resultIndex = new int[2];
resultIndex[0]=map.get(temp);
resultIndex[1]=i;
}else{
map.put(nums[i],i);
}
}
return resultIndex;
}
An O(n) solution in c++ using hash map only exploiting Commutative rule of Addition in real numbers.
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> my_map;
for ( int i = 0 ; i < nums.size(); i++ ){
if(my_map.find(target - nums[i]) != my_map.end()){
return vector<int> {my_map[target - nums[i]], i};
}
my_map[nums[i]] = i ;
}
}
};