किसी सरणी से ऐसे तत्वों की जोड़ी ज्ञात करें, जिनका योग किसी दिए गए संख्या के बराबर है


122

N पूर्णांक की सरणी को देखते हुए और एक संख्या X दिया गया, सभी अद्वितीय युग्म तत्वों (a, b) को खोजें, जिनका योग X के बराबर है।

निम्नलिखित मेरा समाधान है, यह O (nLog (n) + n) है, लेकिन मुझे यकीन नहीं है कि यह इष्टतम है या नहीं।

int main(void)
{
    int arr [10] = {1,2,3,4,5,6,7,8,9,0};
    findpair(arr, 10, 7);
}
void findpair(int arr[], int len, int sum)
{
    std::sort(arr, arr+len);
    int i = 0;
    int j = len -1;
    while( i < j){
        while((arr[i] + arr[j]) <= sum && i < j)
        {
            if((arr[i] + arr[j]) == sum)
                cout << "(" << arr[i] << "," << arr[j] << ")" << endl;
            i++;
        }
        j--;
        while((arr[i] + arr[j]) >= sum && i < j)
        {
            if((arr[i] + arr[j]) == sum)
                cout << "(" << arr[i] << "," << arr[j] << ")" << endl;
            j--;
        }
    }
}

3
यदि आप सरणी को सॉर्ट करने के बजाय किसी तरह के O (1) सेट में सब कुछ चकते हैं तो O (n) समाधान संभव है।
आनन।

1
@ क्या आप अधिक विवरण बता सकते हैं, ऐसे सेट का निर्माण कैसे करें?
जिन १

3
हैश का उपयोग करें। अधिकांश भाषाओं में उनके मानक पुस्तकालयों में कहीं न कहीं एक परिशोधन O (1) हैशसेट होगा।
आनन।

15
एक मामूली नाइट - O (nLog (n) + n) O (nLog (n)) है। बिग ओ नोटेशन केवल प्रमुख पद को बरकरार रखता है और सभी निचले क्रम की शर्तें छोड़ देता है।
PJs

2
नोट शॉर्ट सर्किट मूल्यांकन और ऑफ-बाय-वन एड्रेसिंग: while((arr[i] + arr[j]) <= sum && i < j)होना चाहिए while( i < J && arr[i] + arr[j] <= sum )। (दूसरे सबलूप के लिए समान)
वाइल्डपलासर

जवाबों:


135
# Let arr be the given array.
# And K be the give sum


for i=0 to arr.length - 1 do
  hash(arr[i]) = i  // key is the element and value is its index.
end-for

for i=0 to arr.length - 1 do
  if hash(K - arr[i]) != i  // if Kth element exists and it's different then we found a pair
    print "pair i , hash(K - arr[i]) has sum K"
  end-if
end-for

26
आप पहले लूप में हैश असाइनमेंट के ठीक बाद, दूसरे लूप से अपना स्टेटमेंट डालकर, सरणी के माध्यम से एक पुनरावृत्ति में भी कर सकते हैं।
अलेक्जेंडर कोंड्रेट्सकी

4
माइनर नोट: यह (साथ ही अलेक्जेंडर का सुझाव) कुछ जोड़े को डबल-प्रिंट करेगा, चाहे एक जोड़ी की विशिष्टता सूचकांक द्वारा निर्धारित की जाती है (जैसा कि इस उत्तर से निहित हो सकता है) या मूल्य के अनुसार (जैसा कि ओपी में लगता है)। इंडेक्स द्वारा काफी कुछ (O (n ^ 2)) अद्वितीय जोड़े हो सकते हैं, जैसे arr=[1,2,1,2,1,2,1,...]। मूल्य द्वारा विशिष्टता के लिए, ऐसा लगता है कि मूल्य-जोड़ी द्वारा की गई एक अन्य हैश तालिका चाल को करेगी। अभी भी एक अच्छा, कॉम्पैक्ट, सुरुचिपूर्ण जवाब। +1
विलियम

2
@codaddict लेकिन क्या है अगर सरणी बहुत बड़ी है? मेरा मतलब है कि इसमें मूल्यों की सीमा बहुत बड़ी है? तो, हैश समाधान तो कम व्यावहारिक होगा। उसी के लिए कोई वैकल्पिक और इष्टतम विधि?
प्रशांत सिंह

15
क्या होगा अगर वहाँ डुप्लिकेट हैं?
जद

2
क्या hash(K - arr[i]) != iकिसी तरह दोनों की उपस्थिति और मैच की कमी की जाँच करता है ? मुझे उम्मीद है कि उपस्थिति के लिए एक अलग जाँच होगी।
जोसेफ गार्विन

185

इस समाधान के 3 दृष्टिकोण हैं:

मान को T और n को सरणी का आकार दें

दृष्टिकोण 1:
ऐसा करने का भोला तरीका सभी संयोजनों की जांच करना होगा (एन 2 चुनें)। यह संपूर्ण खोज O (n 2 ) है।

दृष्टिकोण 2: 
 सरणी को सॉर्ट करने का एक बेहतर तरीका होगा। यह O (n log n) लेता है
फिर सरणी A में प्रत्येक x के लिए, Tx देखने के लिए द्विआधारी खोज का उपयोग करें। यह O (nlogn) लेगा।
तो, समग्र खोज हे (एन लॉग एन)

दृष्टिकोण 3:
सबसे अच्छा तरीका यह होगा कि आप हर तत्व को हैश टेबल (बिना छांटे) में डालें। यह O (n) निरंतर समय सम्मिलन के रूप में लेता है।
फिर हर x के लिए, हम इसके पूरक Tx को देख सकते हैं, जो O (1) है।
कुल मिलाकर इस दृष्टिकोण का रन टाइम O (n) है।


आप अधिक उल्लेख कर सकते हैं यहाँ । धन्यवाद।



आप ऐरे के तत्वों के लिए हैश टेबल कैसे बनाएंगे?
सतीश पटेल

मैंने जो लिंक साझा किया है, उसका संदर्भ लें। तत्व को सूचकांक के रूप में संग्रहीत करने के लिए हमारे पास एक समानांतर सरणी हो सकती है, या आप तत्वों को हैशटेबल में जोड़ सकते हैं और उन पर उपयोग कर सकते हैं। ऐसे देर से जवाब के लिए क्षमा करें।
किंशुक ४

11
यदि कोई ऐसा तत्व है जो आधा लक्ष्य राशि का आधा है तो आपको एक गलत सकारात्मक मिल सकता है।
फ्लोरियन एफ

2
@Florian_F क्या आप केवल विशेष मामला नहीं कर सकते हैं, जहां आपके पास एक ऐसा तत्व है जो बिल्कुल आधा है?
जोसफ गार्विन

1
@ जज़्ज़ मेरा मतलब हैशपॉट यहाँ है, हालाँकि हैशसेट भी करेगा। यहाँ कार्यान्वयन है - github.com/kinshuk4/AlgorithmUtil/blob/master/src/com/vaani/… । आशा करता हूँ की ये काम करेगा।
किंशुक

64

जावा में कार्यान्वयन: कोडडक्ट के एल्गोरिथ्म का उपयोग करना (शायद थोड़ा अलग)

import java.util.HashMap;

public class ArrayPairSum {


public static void main(String[] args) {        

    int []a = {2,45,7,3,5,1,8,9};
    printSumPairs(a,10);        

}


public static void printSumPairs(int []input, int k){
    Map<Integer, Integer> pairs = new HashMap<Integer, Integer>();

    for(int i=0;i<input.length;i++){

        if(pairs.containsKey(input[i]))
            System.out.println(input[i] +", "+ pairs.get(input[i]));
        else
            pairs.put(k-input[i], input[i]);
    }

}
}

इनपुट के लिए = {2,45,7,3,5,1,8,9}और यदि सम है10

आउटपुट जोड़े:

3,7 
8,2
9,1

समाधान के बारे में कुछ नोट्स:

  • हम सरणी -> O (n) समय के माध्यम से केवल एक बार पुनरावृति करते हैं
  • हाश में प्रविष्टि और देखने का समय O (1) है।
  • कुल मिलाकर समय O (n) है, हालांकि यह हैश के मामले में अतिरिक्त स्थान का उपयोग करता है।

1
यह तभी अच्छा है जब इनपुट ऐरे ने डुप्लिकेट नहीं किया है।
नरेन

2
@ नारेन: दिए गए एरे में डुप्लिकेट होने पर भी कोई फ़र्क नहीं पड़ता है
abhishek08aug

1
यह लागू नहीं करता है कि कोडैडिकट्स ने क्या लिखा है, और आपने क्या किया, हालांकि यह काम करता है, अनावश्यक रूप से जटिल है। यह अर्थहीन है put(k-input[i], input[i])(कोडैडिकेट्स इंडेक्स को मूल्य के रूप में रखता है जो उपयोगी है।) जो आपने लिखा है उसे सरल बनाया जा सकता हैfor (i:input){ if (intSet.contains(sum-i) { print(i + "," + (sum-i) ); } else {intSet.add(i)}
एड्रियन शम

1
ठीक है शुक्रिया। अन्य लोगों के संदर्भ के उद्देश्य के लिए, मैंने सिर्फ एक और धागा बनाया ताकि यह विश्लेषण करने में कठिनाई हो कि यह समाधान कैसे ठीक से समझ सकता है। यहाँ लिंक है: stackoverflow.com/questions/33274952/…
जॉन

2
@ abhishek08aug यह {1, 1, 1} के लिए काम नहीं करेगा
jbakirov

8

जावा में घोल। आप स्ट्रिंग के एक ArrayList में सभी स्ट्रिंग तत्वों को जोड़ सकते हैं और सूची वापस कर सकते हैं। यहाँ मैं इसे छाप रहा हूँ।

void numberPairsForSum(int[] array, int sum) {
    HashSet<Integer> set = new HashSet<Integer>();
    for (int num : array) {
        if (set.contains(sum - num)) {
            String s = num + ", " + (sum - num) + " add up to " + sum;
            System.out.println(s);
        }
        set.add(num);
    }
}

4

पायथन कार्यान्वयन:

import itertools
list = [1, 1, 2, 3, 4, 5,]
uniquelist = set(list)
targetsum = 5
for n in itertools.combinations(uniquelist, 2):
    if n[0] + n[1] == targetsum:
        print str(n[0]) + " + " + str(n[1])

आउटपुट:

1 + 4
2 + 3

2
में देखो ... तत्व खोज के लिए उपरि हो जाएगा
निखिल रूपनवार

4

C ++ 11, रन टाइम जटिलता O (n):

#include <vector>
#include <unordered_map>
#include <utility>

std::vector<std::pair<int, int>> FindPairsForSum(
        const std::vector<int>& data, const int& sum)
{
    std::unordered_map<int, size_t> umap;
    std::vector<std::pair<int, int>> result;
    for (size_t i = 0; i < data.size(); ++i)
    {
        if (0 < umap.count(sum - data[i]))
        {
            size_t j = umap[sum - data[i]];
            result.push_back({data[i], data[j]});
        }
        else
        {
            umap[data[i]] = i;
        }
    }

    return result;
}

3

यहाँ एक समाधान डायन डुप्लिकेट प्रविष्टियों को ध्यान में रखता है। यह जावास्क्रिप्ट में लिखा गया है और माना जाता है कि सरणी को क्रमबद्ध किया गया है। समाधान ओ (एन) समय में चलता है और चर से अलग किसी भी अतिरिक्त मेमोरी का उपयोग नहीं करता है।

var count_pairs = function(_arr,x) {
  if(!x) x = 0;
  var pairs = 0;
  var i = 0;
  var k = _arr.length-1;
  if((k+1)<2) return pairs;
  var halfX = x/2; 
  while(i<k) {
    var curK = _arr[k];
    var curI = _arr[i];
    var pairsThisLoop = 0;
    if(curK+curI==x) {
      // if midpoint and equal find combinations
      if(curK==curI) {
        var comb = 1;
        while(--k>=i) pairs+=(comb++);
        break;
      }
      // count pair and k duplicates
      pairsThisLoop++;
      while(_arr[--k]==curK) pairsThisLoop++;
      // add k side pairs to running total for every i side pair found
      pairs+=pairsThisLoop;
      while(_arr[++i]==curI) pairs+=pairsThisLoop;
    } else {
      // if we are at a mid point
      if(curK==curI) break;
      var distK = Math.abs(halfX-curK);
      var distI = Math.abs(halfX-curI);
      if(distI > distK) while(_arr[++i]==curI);
      else while(_arr[--k]==curK);
    }
  }
  return pairs;
}

मैंने इसे एक बड़े निगम के लिए एक साक्षात्कार के दौरान हल किया। उन्होंने इसे लिया लेकिन मुझे नहीं। तो यहाँ यह सभी के लिए है।

सरणी के दोनों ओर शुरू करें और धीरे-धीरे अपने तरीके से अंदर की ओर काम करें ताकि वे मौजूद होने पर डुप्लिकेट की गिनती सुनिश्चित कर सकें।

यह केवल जोड़े को गिनता है, लेकिन इसे फिर से काम में लाया जा सकता है

  • जोड़े खोजें
  • जोड़े खोजें <x
  • जोड़े खोजें> एक्स

का आनंद लें!


ये पंक्तियाँ क्या करती हैं ?: if(distI > distK) while(_arr[++i]==curI); else while(_arr[--k]==curK);
यूरी चेर्नशॉ

ये रेखाएं दोनों ओर से डुप्लिकेट मानों के माध्यम से छोड़ती हैं और उन्हें जोड़े के रूप में गिनाती हैं यदि वे एक जोड़ी योग = एन का हिस्सा हैं
ड्रोन ब्रेन

3

पर)

def find_pairs(L,sum):
    s = set(L)
    edgeCase = sum/2
    if L.count(edgeCase) ==2:
        print edgeCase, edgeCase
    s.remove(edgeCase)      
    for i in s:
        diff = sum-i
        if diff in s: 
            print i, diff


L = [2,45,7,3,5,1,8,9]
sum = 10          
find_pairs(L,sum)

कार्यप्रणाली: a + b = c, इसलिए हम (a, b) की तलाश करने के बजाय a = c - b की तलाश करते हैं


यदि आप इनपुट में डुप्लिकेट है, तो इस तरह से मत जागना: [3, 4, 3, 2, 5] और योग = 6
एंटोन डैनिलचेंको

सभी किनारे के मामलों को ठीक किया, अब कोशिश करें
garg10may

2

जावा में कार्यान्वयन: कोडडक्ट के एल्गोरिथ्म का उपयोग करना:

import java.util.Hashtable;
public class Range {

public static void main(String[] args) {
    // TODO Auto-generated method stub
    Hashtable mapping = new Hashtable();
    int a[]= {80,79,82,81,84,83,85};
    int k = 160;

    for (int i=0; i < a.length; i++){
        mapping.put(a[i], i);
    }

    for (int i=0; i < a.length; i++){
        if (mapping.containsKey(k - a[i]) && (Integer)mapping.get(k-a[i]) != i){
            System.out.println(k-a[i]+", "+ a[i]);
        }
    }      

}

}

आउटपुट:

81, 79
79, 81

अगर आप डुप्लीकेट पेयर (जैसे: 80,80) चाहते हैं तो बस && (Integer) मैपिंग हटाएं (ka [i])! = I से अगर मैं कंडीशन करता हूं और आप जाना अच्छा मानते हैं।


C # के लिए यह काम हो सकता है - int k = 16; int count = 0; int [] intArray = {5, 7, 11, 23,8,9,15,1,10,6}; for (int i = 0; मैं <intArray.Length; i ++) {for (int j = i; j <intArray.Length; j ++) {if ((k - intArray [i]) == intrrray [j]) { ++ गिनती; }}} Console.WriteLine (गिनती);
मुकुलशर्मा

2

HackerRank पर इस सवाल का जवाब दिया और यहाँ मेरा 'उद्देश्य C' समाधान है :

-(NSNumber*)sum:(NSArray*) a andK:(NSNumber*)k {
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    long long count = 0;
    for(long i=0;i<a.count;i++){

        if(dict[a[i]]) {
            count++;
            NSLog(@"a[i]: %@, dict[array[i]]: %@", a[i], dict[a[i]]);
        }
        else{
            NSNumber *calcNum = @(k.longLongValue-((NSNumber*)a[i]).longLongValue);
            dict[calcNum] = a[i];
        }

    }
    return @(count);
}

आशा है कि यह किसी की मदद करता है।


कोड सिंटैक्स एल्गोरिदम से ही समझना मुश्किल है! :)
राजेंद्र उप्पल

1

यह लूप के अंदर द्विआधारी खोज कार्यान्वयन का उपयोग करके ओ (n * lg n) का कार्यान्वयन है।

#include <iostream>

using namespace std;

bool *inMemory;


int pairSum(int arr[], int n, int k)
{
    int count = 0;

    if(n==0)
        return count;
    for (int i = 0; i < n; ++i)
    {
        int start = 0;
        int end = n-1;      
        while(start <= end)
        {
            int mid = start + (end-start)/2;
            if(i == mid)
                break;
            else if((arr[i] + arr[mid]) == k && !inMemory[i] && !inMemory[mid])
            {
                count++;
                inMemory[i] = true;
                inMemory[mid] = true;
            }
            else if(arr[i] + arr[mid] >= k)
            {
                end = mid-1;
            }
            else
                start = mid+1;
        }
    }
    return count;
}


int main()
{
    int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    inMemory = new bool[10];
    for (int i = 0; i < 10; ++i)
    {
        inMemory[i] = false;
    }
    cout << pairSum(arr, 10, 11) << endl;
    return 0;
}


1

कोडेडडिक्ट से अच्छा समाधान। मैंने रूबी में इसके एक संस्करण को लागू करने की स्वतंत्रता ली:

def find_sum(arr,sum)
 result ={}
 h = Hash[arr.map {|i| [i,i]}]
 arr.each { |l| result[l] = sum-l  if h[sum-l] && !result[sum-l]  }
 result
end

डुप्लिकेट जोड़े (1,5), (5,1) की अनुमति देने के लिए हमें बस && !result[sum-l]निर्देश को निकालना होगा


1

यहाँ तीन दृष्टिकोणों के लिए जावा कोड है:
1. मैप ओ (एन) का उपयोग करके, हैशसेट का उपयोग यहां भी किया जा सकता है।
2. क्रमबद्ध सरणी और फिर O (nLog (n)) पूरक के लिए देखने के लिए BinarySearch का उपयोग करें
। पारंपरिक BruteForce दो छोरों O (n ^ 2)

public class PairsEqualToSum {

public static void main(String[] args) {
    int a[] = {1,10,5,8,2,12,6,4};
    findPairs1(a,10);
    findPairs2(a,10);
    findPairs3(a,10);

}


//Method1 - O(N) use a Map to insert values as keys & check for number's complement in map
    static void findPairs1(int[]a, int sum){
        Map<Integer, Integer> pairs = new HashMap<Integer, Integer>();
        for(int i=0; i<a.length; i++){
            if(pairs.containsKey(sum-a[i]))
                System.out.println("("+a[i]+","+(sum-a[i])+")");
            else
               pairs.put(a[i], 0);
        }
    }



//Method2 - O(nlog(n)) using Sort
static void findPairs2(int[]a, int sum){
        Arrays.sort(a);
        for(int i=0; i<a.length/2; i++){
            int complement = sum - a[i];
            int foundAtIndex = Arrays.binarySearch(a,complement);
            if(foundAtIndex >0 && foundAtIndex != i) //to avoid situation where binarySearch would find the original and not the complement like "5"
                System.out.println("("+a[i]+","+(sum-a[i])+")");
        }
 }

//Method 3 - Brute Force O(n^2)
static void findPairs3(int[]a, int sum){

    for(int i=0; i<a.length; i++){
        for(int j=i; j<a.length;j++){
            if(a[i]+a[j] == sum)
                System.out.println("("+a[i]+","+a[j]+")");
        }
    }
}

}

1

अद्वितीय तत्वों वाले सरणियों के लिए जावा में एक सरल कार्यक्रम:

import java.util.*;
public class ArrayPairSum {
    public static void main(String[] args) { 
        int []a = {2,4,7,3,5,1,8,9,5};
        sumPairs(a,10);  
    }

    public static void sumPairs(int []input, int k){
      Set<Integer> set = new HashSet<Integer>();    
      for(int i=0;i<input.length;i++){

        if(set.contains(input[i]))
            System.out.println(input[i] +", "+(k-input[i]));
        else
            set.add(k-input[i]);
       }
    }
}

1

नीचे दिए गए जोड़ों को प्रिंट करने के लिए एक सरल जावा कोड स्निपेट:

    public static void count_all_pairs_with_given_sum(int arr[], int S){
        if(arr.length < 2){
        return;
    }        
    HashSet values = new HashSet(arr.length);
    for(int value : arr)values.add(value);
    for(int value : arr){
        int difference = S - value;
    if(values.contains(difference) && value<difference){
        System.out.printf("(%d, %d) %n", value, difference);
        }
    }
    }

1

स्विफ्ट में एक अन्य समाधान: विचार एक हैश बनाने के लिए है जो (राशि - currentValue) के मूल्यों को संग्रहीत करता है और लूप के वर्तमान मूल्य से इसकी तुलना करता है। जटिलता O (n) है।

func findPair(list: [Int], _ sum: Int) -> [(Int, Int)]? {
    var hash = Set<Int>() //save list of value of sum - item.
    var dictCount = [Int: Int]() //to avoid the case A*2 = sum where we have only one A in the array
    var foundKeys  = Set<Int>() //to avoid duplicated pair in the result.

    var result = [(Int, Int)]() //this is for the result.
    for item in list {

        //keep track of count of each element to avoid problem: [2, 3, 5], 10 -> result = (5,5)
        if (!dictCount.keys.contains(item)) {
            dictCount[item] = 1
        } else {
            dictCount[item] = dictCount[item]! + 1
        }

        //if my hash does not contain the (sum - item) value -> insert to hash.
        if !hash.contains(sum-item) {
            hash.insert(sum-item)
        }

        //check if current item is the same as another hash value or not, if yes, return the tuple.
        if hash.contains(item) &&
            (dictCount[item] > 1 || sum != item*2) // check if we have item*2 = sum or not.
        {
            if !foundKeys.contains(item) && !foundKeys.contains(sum-item) {
                foundKeys.insert(item) //add to found items in order to not to add duplicated pair.
                result.append((item, sum-item))
            }
        }
    }
    return result
}

//test:
let a = findPair([2,3,5,4,1,7,6,8,9,5,3,3,3,3,3,3,3,3,3], 14) //will return (8,6) and (9,5)

1

मेरा समाधान - जावा - डुप्लिकेट के बिना

    public static void printAllPairSum(int[] a, int x){
    System.out.printf("printAllPairSum(%s,%d)\n", Arrays.toString(a),x);
    if(a==null||a.length==0){
        return;
    }
    int length = a.length;
    Map<Integer,Integer> reverseMapOfArray = new HashMap<>(length,1.0f);
    for (int i = 0; i < length; i++) {
        reverseMapOfArray.put(a[i], i);
    }

    for (int i = 0; i < length; i++) {
        Integer j = reverseMapOfArray.get(x - a[i]);
        if(j!=null && i<j){
            System.out.printf("a[%d] + a[%d] = %d + %d = %d\n",i,j,a[i],a[j],x);
        }
    }
    System.out.println("------------------------------");
}

0

यह जोड़े को प्रिंट करता है और बिटवाइज़ हेरफेर का उपयोग करके डुप्लिकेट से बचा जाता है।

public static void findSumHashMap(int[] arr, int key) {
    Map<Integer, Integer> valMap = new HashMap<Integer, Integer>();
    for(int i=0;i<arr.length;i++)
        valMap.put(arr[i], i);

    int indicesVisited = 0; 
    for(int i=0;i<arr.length;i++) {
        if(valMap.containsKey(key - arr[i]) && valMap.get(key - arr[i]) != i) {
            if(!((indicesVisited & ((1<<i) | (1<<valMap.get(key - arr[i])))) > 0)) {
                int diff = key-arr[i];
                System.out.println(arr[i] + " " +diff);
                indicesVisited = indicesVisited | (1<<i) | (1<<valMap.get(key - arr[i]));
            }
        }
    }
}

0

मैंने थोड़ा मनुस्मरण को दरकिनार कर दिया और सिर्फ सूचकांक मूल्यों की तुलना की। यह लूप पुनरावृत्ति मूल्य से कम है (मैं इस मामले में)। यह डुप्लिकेट जोड़े और डुप्लिकेट सरणी तत्वों को भी प्रिंट नहीं करेगा।

public static void findSumHashMap(int[] arr, int key) {
    Map<Integer, Integer> valMap = new HashMap<Integer, Integer>();
    for (int i = 0; i < arr.length; i++) {
        valMap.put(arr[i], i);
    }
    for (int i = 0; i < arr.length; i++) {
        if (valMap.containsKey(key - arr[i])
                && valMap.get(key - arr[i]) != i) {
            if (valMap.get(key - arr[i]) < i) {
                int diff = key - arr[i];
                System.out.println(arr[i] + " " + diff);
            }
        }
    }
}

0

C # में:

        int[] array = new int[] { 1, 5, 7, 2, 9, 8, 4, 3, 6 }; // given array
        int sum = 10; // given sum
        for (int i = 0; i <= array.Count() - 1; i++)
            if (array.Contains(sum - array[i]))
                Console.WriteLine("{0}, {1}", array[i], sum - array[i]);

यह उत्तर अधिक उपयोगी होगा यदि आप अपने समाधान के विकास के क्रम का वर्णन करते हैं
थॉमस

0

एक समाधान यह हो सकता है, लेकिन ऑप्टिमुल नहीं है (इस कोड की जटिलता हे (n ^ 2)):

public class FindPairsEqualToSum {

private static int inputSum = 0;

public static List<String> findPairsForSum(int[] inputArray, int sum) {
    List<String> list = new ArrayList<String>();
    List<Integer> inputList = new ArrayList<Integer>();
    for (int i : inputArray) {
        inputList.add(i);
    }
    for (int i : inputArray) {
        int tempInt = sum - i;
        if (inputList.contains(tempInt)) {
            String pair = String.valueOf(i + ", " + tempInt);
            list.add(pair);
        }
    }
    return list;
   }
}

0

कोड का एक सरल पायथन संस्करण जो शून्य की एक जोड़ी राशि ढूंढता है और k खोजने के लिए संशोधित किया जा सकता है:

def sumToK(lst):
    k = 0  # <- define the k here
    d = {} # build a dictionary 

# build the hashmap key = val of lst, value = i
for index, val in enumerate(lst):
    d[val] = index

# find the key; if a key is in the dict, and not the same index as the current key
for i, val in enumerate(lst):
    if (k-val) in d and d[k-val] != i:
        return True

return False

फ़ंक्शन की रन टाइम जटिलता O (n) और Space: O (n) भी है।


0
 public static int[] f (final int[] nums, int target) {
    int[] r = new int[2];
    r[0] = -1;
    r[1] = -1;
    int[] vIndex = new int[0Xfff];
    for (int i = 0; i < nums.length; i++) {
        int delta = 0Xff;
        int gapIndex = target - nums[i] + delta;
        if (vIndex[gapIndex] != 0) {
            r[0] = vIndex[gapIndex];
            r[1] = i + 1;
            return r;
        } else {
            vIndex[nums[i] + delta] = i + 1;
        }
    }
    return r;
}


0

सूची समझ का उपयोग करके पायथन में समाधान

f= [[i,j] for i in list for j in list if j+i==X];

ओ (एन 2 )

साथ ही दो ऑर्डर किए गए जोड़े- (ए, बी) और (बी, ए) भी देता है


आप एक भाषा का उल्लेख कर सकते हैं, चाहे जोड़े (ए, बी) और (बी) अद्वितीय हैं, और इस सवाल का क्या जवाब है (प्रश्न में एक स्पष्ट नहीं है - I am not sure … Thanks for comments)। आप ओ (n।) के करीब जटिलता पर छुरा भोंक सकते हैं।
ग्रेबियर्ड

0

मैं इसे O (n) में कर सकता हूं। मुझे पता है जब आप जवाब चाहते हैं। ध्यान दें कि इसमें किसी भी प्रकार की छँटाई के साथ एक बार सरणी का पता लगाना शामिल है, आदि ... मुझे यह भी उल्लेख करना चाहिए कि यह इसके अतिरिक्त की कमनीयता का शोषण करता है और हैश का उपयोग नहीं करता है लेकिन स्मृति को बर्बाद करता है।


सिस्टम का उपयोग; System.Collections.Generic का उपयोग कर;

/ * एक O (n) दृष्टिकोण लुकअप तालिका का उपयोग करके मौजूद है। दृष्टिकोण एक "बिन" में मूल्य को संग्रहीत करना है जिसे आसानी से देखा जा सकता है (जैसे, ओ (1)) यदि यह एक उपयुक्त राशि का उम्मीदवार है।

जैसे,

सरणी में प्रत्येक [k] के लिए हम इसे स्थान x - [a] पर दूसरे सरणी में रखते हैं।

मान लीजिए हमारे पास [0, 1, 5, 3, 6, 9, 8, 7] और x = 9 है

हम एक नई सरणी बनाते हैं,

सूचकांक मूल्य

9 - 0 = 9     0
9 - 1 = 8     1
9 - 5 = 4     5
9 - 3 = 6     3
9 - 6 = 3     6
9 - 9 = 0     9
9 - 8 = 1     8
9 - 7 = 2     7

केवल उन्हीं मूल्यों को महत्व देते हैं जो नई तालिका में एक सूचकांक हैं।

इसलिए, यह कहें कि जब हम 9 या उसके बराबर पहुँचते हैं तो हम देखते हैं कि हमारे नए सरणी में सूचकांक 9 - 9 = 0. है क्योंकि हमें पता है कि इसमें शामिल सभी मान 9. में जोड़ देंगे (ध्यान दें कि इस कारण से यह स्पष्ट है कि केवल यही है 1 संभव एक लेकिन इसमें कई सूचकांक मूल्य हो सकते हैं जिन्हें हमें संग्रहीत करने की आवश्यकता है)।

इतनी प्रभावी रूप से हम जो कर रहे हैं वह केवल एक बार सरणी के माध्यम से आगे बढ़ना है। क्योंकि इसके अलावा सराहनीय है कि हम सभी संभावित परिणामों को समाप्त कर देंगे।

उदाहरण के लिए, जब हम 6 पर पहुँचते हैं, तो हम अपनी नई तालिका में 9 - 6 = 3. के रूप में सूचकांक प्राप्त करते हैं, क्योंकि तालिका में उस सूचकांक मान होता है जिसे हम मूल्यों को जानते हैं।

यह अनिवार्य रूप से मेमोरी के लिए गति को बंद कर रहा है। * /

namespace sum
{
    class Program
    {
        static void Main(string[] args)
        {
            int num = 25;
            int X = 10;
            var arr = new List<int>();
            for(int i = 0; i <= num; i++) arr.Add((new Random((int)(DateTime.Now.Ticks + i*num))).Next(0, num*2));
            Console.Write("["); for (int i = 0; i < num - 1; i++) Console.Write(arr[i] + ", "); Console.WriteLine(arr[arr.Count-1] + "] - " + X);
            var arrbrute = new List<Tuple<int,int>>();
            var arrfast = new List<Tuple<int,int>>();

            for(int i = 0; i < num; i++)
            for(int j = i+1; j < num; j++)
                if (arr[i] + arr[j] == X) 
                    arrbrute.Add(new Tuple<int, int>(arr[i], arr[j]));




            int M = 500;
            var lookup = new List<List<int>>();
            for(int i = 0; i < 1000; i++) lookup.Add(new List<int>());
            for(int i = 0; i < num; i++)        
            {
                // Check and see if we have any "matches"
                if (lookup[M + X - arr[i]].Count != 0)
                {
                    foreach(var j in lookup[M + X - arr[i]])
                    arrfast.Add(new Tuple<int, int>(arr[i], arr[j])); 
                }

                lookup[M + arr[i]].Add(i);

            }

            for(int i = 0; i < arrbrute.Count; i++)
                Console.WriteLine(arrbrute[i].Item1 + " + " + arrbrute[i].Item2 + " = " + X);
            Console.WriteLine("---------");
            for(int i = 0; i < arrfast.Count; i++)
                Console.WriteLine(arrfast[i].Item1 + " + " + arrfast[i].Item2 + " = " + X);

            Console.ReadKey();
        }
    }
}

मूल रूप से हैश से बचने के लिए हमें एक तालिका बनानी होगी जो कुछ मनमाने सूचकांकों पर यादृच्छिक सम्मिलन को स्वीकार कर सके। इसलिए मैं यह सुनिश्चित करने के लिए एम का उपयोग करता हूं कि पर्याप्त तत्व हैं और एक सन्निहित सेट को पूर्व-आवंटित करते हैं, भले ही अधिकांश का उपयोग नहीं किया जाएगा। एक हैश सेट सीधे इसका ख्याल रखेगा।
AbstractDissonance

तो, आप एक हैश फ़ंक्शन के साथ एक हैश सेट का उपयोग कर रहे हैं और आपके हैश फ़ंक्शन के अधिकतम मूल्य से अधिक है?
क्रिस होपमैन

इस बिंदु पर अपने हैश फ़ंक्शन के लिए पहचान फ़ंक्शन का भी उपयोग कर सकते हैं। यही है, [k] -th "बिन" पर एक [k] रखो।
क्रिस होपमैन

क्योंकि एक [के] और एक्स - एक [के] को एक सूचकांक का उपयोग किया जाता है और मैं एक सरणी का उपयोग कर रहा हूं, इसका मतलब है कि न्यूनतम सूचकांक 0. नहीं हो सकता है। इसलिए मैं बस उन्हें स्थानांतरित करने के लिए एक बहुत बड़ी संख्या जोड़ता हूं। यदि कोई हैश फ़ंक्शन कर सकता है जो मनमाने मूल्यों के लिए काम करता है तो वे इस स्थानांतरण को किए बिना एक सरल सूची का उपयोग कर सकते हैं। स्थानांतरण + उपदेश एक हैश बनाने से बचने में मदद करता है (या यह एक बहुत ही सरल (और तेज) हैश के बारे में सोचा जा सकता है)।
AbstractDissonance

-1

जावास्क्रिप्ट समाधान:

var sample_input = [0, 1, 100, 99, 0, 10, 90, 30, 55, 33, 55, 75, 50, 51, 49, 50, 51, 49, 51];
var result = getNumbersOf(100, sample_input, true, []);

function getNumbersOf(targetNum, numbers, unique, res) {
    var number = numbers.shift();

    if (!numbers.length) {
        return res;
    }

    for (var i = 0; i < numbers.length; i++) {
        if ((number + numbers[i]) === targetNum) {
            var result = [number, numbers[i]];
            if (unique) {
              if (JSON.stringify(res).indexOf(JSON.stringify(result)) < 0) {
                res.push(result);                
              }
            } else {
              res.push(result);
            }
            numbers.splice(numbers.indexOf(numbers[i]), 1);
            break;
        }
    }
    return getNumbersOf(targetNum, numbers, unique, res);
}

बहुत ही प्रफुल्लित .... आप स्ट्रिंग का उपयोग कर रहे हैं (ओ (एन) समय और स्थान) प्रत्येक पुनरावृत्ति ..
Aviad


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.