0

This is my code for creating a linked list:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

typedef struct list_element {
    int inf;
    struct list_element *next;
} List;

List *create() {
    List *p, *punt;
    int x = 1;/*Random number but different from 0*/
    p = (List *)malloc(sizeof(List));
    printf("\nFirst value: ");
    scanf("%d", &p->inf);
    punt = p;

    while (1) {/*Till x different from 0*/
        printf("\nNext value: ");
        scanf("%d", &x);
        if (x == 0)
            break;
        punt->next = (List *)malloc(sizeof(List));
        punt = punt->next;
        punt->inf = x;
    }
    punt->next = NULL;
    return p;
}

int main(void) {
    List *a;
    a = create();
}

Suppose the following values to be sent in input(scanf):

10 20 30 40 50 15 35

I need to create a void function which sends to stdout the list of pairs of numbers whose sum is 50, so in this case the output will be

10 40

20 30

15 35

To do this I used two different functions:
In the first I copied the the value of the linked list in an array of int and in the second function, with a backtracking algorithm (performed on the array just created) I found the solutions.
This is my solution:

void BackTrack(int n, int s, int x[7], int z[7], int partial, int max, int check) {
    if (n == s) {
        int y = 0;
        for (int i = 0; i < n; i++){
            if (z[i] != 0 && check == 2 && partial == max) {
                printf("%d ", z[i]);
                y++;
            }
        }
        if(y != 0)
            printf("\n");
        return;
    }

    z[s] = 0;
    BackTrack(n, s + 1, x, z, partial, max, check);

    if (x[s] + partial <= max) {
        z[s] = x[s];
        partial += x[s];
        check++;
        BackTrack(n, s + 1, x, z, partial, max, check);
    }
}

void ARRAY(List *p) {
    int *x = NULL;
    int i;
    for (i = 0; p != NULL; i++){
        x = realloc(x, sizeof(int) * (i + 1));
        x[i] = p->inf;
        p = p->next;
    }
    int *z = malloc(sizeof(int) * i);
    BackTrack(i, 0, x, z, 0, 50, 0);
}

But I wanna know if there is a way to do this without using before an array conversation as I did? So to fint directly the couples on the linked list. Thanks

Community
  • 1
  • 1
Amarildo
  • 268
  • 4
  • 19
  • Possible duplicate of [Design an algorithm to find all pairs of integers within an array which sum to a specified value](http://stackoverflow.com/questions/1494130/design-an-algorithm-to-find-all-pairs-of-integers-within-an-array-which-sum-to-a) – Saeid Sep 30 '16 at 10:59
  • @Tempux not really, i do not want to find pairs in the array (because I already proposed here above my solution with that method), i wanted to know if there is a way to do the same thing but on a linked list – Amarildo Sep 30 '16 at 11:02
  • Can the list be changed destructive ? – BLUEPIXY Sep 30 '16 at 11:06
  • 2
    `p = (List *)malloc(sizeof(List));` <-- please don't cast the return of `malloc` & co. It's required in C++, but considered harmful in C – Elias Van Ootegem Sep 30 '16 at 11:10
  • @EliasVanOotegem Ok thanks for the advice – Amarildo Sep 30 '16 at 11:11

3 Answers3

2
void FindPairs(List *list, int sum) {

  struct list_element *i, *j;

  for (i = list; i; i = i->next) {
    if (i->inf > sum)
      continue;
    for (j = i->next; j; j = j->next) {
      if (i->inf + j->inf == sum)
        printf("%d %d\n", i->inf, j->inf);
    }
  }
}
G. Sliepen
  • 7,637
  • 1
  • 15
  • 31
0
  1. Simple method would be using 2 for loops over the list and check for required sum, Complexity - O(n^2).

  2. Use hashmap, store first value in hash map, now from 2nd value, if sum-2ndValue exist in hashmap, your solution, else insert in hashmap. - Time Complexity - O(n), Space Complexity - O(n).

instance
  • 1,366
  • 15
  • 23
-1

I you have the space, copy all values in a sorted data structure like a sorted list. Than you can simultan iterate from both sides and find the pairs this way.

Speed:

  • create the sorted list: O(n log n)
  • iterate to find the pairs: O(n)

if you have not enough space, you need to iterate through the linked list very often.

Pseudocode:

nodeLeft=fistNodeInList
while(nodeLeft.hasNext)
  nodeRight=nodeLeft
  while(nodeRight.hasNext)
    nodeRight= nodeRight.next
    if(nodeRight.value+nodeLeft.value= sum
      print odeRight.value nodeLeft.value
  nodeLeft=nodeLeft.next

This has O(n²) speed

MrSmith42
  • 9,961
  • 6
  • 38
  • 49