📜  在给定的排序链表中打印所有总和为 S 的三元组

📅  最后修改于: 2022-05-13 01:56:08.730000             🧑  作者: Mango

在给定的排序链表中打印所有总和为 S 的三元组

给定一个排序的单链表作为N个不同节点的列表(没有两个节点具有相同的数据)和一个整数S 。任务是在列表中找到所有不同的三元组,它们总和为给定整数 S。

例子:

天真的方法:使用三个嵌套循环。生成所有三元组并找到总和等于 S 的不同三元组。
时间复杂度: O(N 3 )
辅助空间: O(N 3 )

高效的方法:使用散列的概念来有效地解决问题。按照下面提到的步骤

  1. 创建一个哈希数组来存储扫描的节点数据。
  2. 将头节点值插入哈希数组。
  3. 现在开始使用嵌套循环遍历链表,并且在每次迭代中:
    • 从给定的整数“S”中减去两个节点的数据以找到构成三元组的值。
    • 现在在哈希数组中找到该值。
    • 如果该值存在于哈希数组中(即找到三元组),则将三元组存储在一个列表中作为可能的答案。
  4. 返回列表。

下面是上述方法的实现:

C++
// C++ code to find
// all distinct triplets having sum S
#include 
using namespace std;
 
// Structure of node of singly linked list
struct Node {
    int data;
    Node* next;
    Node(int x)
    {
        data = x;
        next = NULL;
    }
};
 
// Inserting new node
// at the  beginning of the linked list
void push(struct Node** head_ref,
          int new_data)
{
    // Create a new node with the given data.
    struct Node* new_node
      = new Node(new_data);
     
    // Make the new node point to the head.
    new_node->next = (*head_ref);
     
    // Make the new node as the head node.
    (*head_ref) = new_node;
}
 
// Function to print triplets
// in a sorted singly linked list
// whose sum is equal to given value 'S'
vector>
  printTriplets(struct Node* head, int S)
{
    // Declare unordered map
    // to store the scanned value
    unordered_map mp;
     
    // Vector to store the triplets
    vector> v;
 
    // Declare two pointers 'p' and 'q'
    // for traversing singly linked list
    struct Node* p;
    struct Node* q;
 
    // Insert 1st node data into map
    // and start traversing from next node
    mp[head->data] = true;
 
    // Outer loop terminates
    // when last node reached
    for (p = head->next; p->next != NULL;
         p = p->next) {
 
        // Inner loop terminates
        // when second pointer become NULL
        for (q = p->next; q != NULL;
             q = q->next) {
 
            // Temporary vector
            // to store the current triplet
            vector temp;
            int second = p->data;
            int third = q->data;
 
            // find the number required
            // to make triplet by subtracting
            // node1 and node2 data from S
            // and store it.
            int first = S - second - third;
 
            // Search if that value
            // is present in the map or not
            if (mp.find(first)
                != mp.end()) {
 
                // If 'first' is present
                // in map, make a triplet of
                // first,second & third
                temp.push_back(mp.find(first)->first);
                temp.push_back(second);
                temp.push_back(third);
 
                // Push current triplet
                // stored in 'temp' to
                // vector 'v'
                v.push_back(temp);
            }
        }
         
        // Insert current node data into map
        mp[p->data] = true;
    }
     
    // Return a vector of triplets.
    return v;
}
 
// Driver code
int main()
{
    int S = 15;
     
    // Create an empty singly linked list
    struct Node* head = NULL;
    vector > ans;
 
    // Insert values in sorted order
    push(&head, 9);
    push(&head, 8);
    push(&head, 6);
    push(&head, 5);
    push(&head, 4);
    push(&head, 2);
    push(&head, 1);
     
    // Call printTriplets function
    // to find all triplets in
    // the linked list
    ans = printTriplets(head, S);
 
    // Sort and  display
    // all possible triplets
    sort(ans.begin(), ans.end());
    for (int i = 0; i < ans.size(); i++) {
        for (int j = 0;
             j < ans[i].size(); j++) {
            cout << ans[i][j] << " ";
        }
        cout << "\n";
    }
    return 0;
}


Java
// Java code to find
// all distinct triplets having sum S
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
 
class GFG
{
   
    // Structure of node of singly linked list
    static class Node {
        int data;
        Node next;
 
        public Node(int x) {
            data = x;
            next = null;
        }
    };
 
    // Function to print triplets
    // in a sorted singly linked list
    // whose sum is equal to given value 'S'
    public static ArrayList> printTriplets(Node head, int S) {
        // Declare unordered map
        // to store the scanned value
        HashMap mp = new HashMap();
 
        // Vector to store the triplets
        ArrayList> v = new ArrayList>();
 
        // Declare two pointers 'p' and 'q'
        // for traversing singly linked list
        Node p;
        Node q;
 
        // Insert 1st node data into map
        // and start traversing from next node
        mp.put(head.data, true);
 
        // Outer loop terminates
        // when last node reached
        for (p = head.next; p.next != null; p = p.next) {
 
            // Inner loop terminates
            // when second pointer become null
            for (q = p.next; q != null; q = q.next) {
 
                // Temporary vector
                // to store the current triplet
                ArrayList temp = new ArrayList();
                int second = p.data;
                int third = q.data;
 
                // find the number required
                // to make triplet by subtracting
                // node1 and node2 data from S
                // and store it.
                int first = S - second - third;
 
                // Search if that value
                // is present in the map or not
                if (mp.containsKey(first)) {
 
                    // If 'first' is present
                    // in map, make a triplet of
                    // first,second & third
                    temp.add(first);
                    temp.add(second);
                    temp.add(third);
 
                    // Push current triplet
                    // stored in 'temp' to
                    // vector 'v'
                    v.add(temp);
                }
            }
 
            // Insert current node data into map
            mp.put(p.data, true);
        }
 
        // Return a vector of triplets.
        return v;
    }
 
    // Driver code
    public static void main(String args[]) {
        int S = 15;
 
        // Create an empty singly linked list
        Node head = null;
        ArrayList> ans = new ArrayList>();
 
        // Insert values in sorted order
        head = new Node(9);
        head.next = new Node(8);
        head.next.next = new Node(6);
        head.next.next.next = new Node(5);
        head.next.next.next.next = new Node(4);
        head.next.next.next.next.next = new Node(2);
        head.next.next.next.next.next.next = new Node(1);
 
        // Call printTriplets function
        // to find all triplets in
        // the linked list
        ans = printTriplets(head, S);
 
        // Sort and display
        // all possible triplets
        for (ArrayList x : ans) {
            Collections.sort(x);
        }
 
        Collections.sort(ans, new Comparator>() {
            @Override
            public int compare(ArrayList o1, ArrayList o2) {
                return o2.get(0) - (o1.get(0));
            }
        });
        Collections.reverse(ans);
 
        for (int i = 0; i < ans.size(); i++) {
            for (int j = 0; j < ans.get(i).size(); j++) {
                System.out.print(ans.get(i).get(j) + " ");
            }
            System.out.println("");
        }
    }
}
 
// This code is contributed by gfgking.


Javascript



输出
1 5 9 
1 6 8 
2 4 9 
2 5 8 
4 5 6 

时间复杂度: O(N 2 )
辅助空间: O(N)