从列表中查找至少两个元素相等的所有最大子列表

时间:2017-08-08 13:23:16

标签: algorithm scala graph connected-components set-operations

给定一个对象列表和一个非传递相等函数,当两个对象相等时返回true,否则返回false,我需要找到至少两个对象相等的所有最大子列表。例如 -

<?php

$Option1 = $_POST["Select-Row"];
$conn = mysqli_connect("localhost","root","");
mysqli_select_db($conn,"test");


header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=wpqf_student_registered.csv');

// create a file pointer connected to the output stream
$output = fopen('php://output', 'w');

// output the column headings
fputcsv($output, array($Option1, 'Column 2', 'Column 3'));

// fetch the data

$rows = mysqli_query($conn ,'SELECT '.$Option1.' FROM wpqf_student_registered');

while ($row = mysqli_fetch_assoc($rows)) {
fputcsv($output, $row);
}
fclose($output);

?>

和,

val list = List(o1, o2, o3, o4, o5)

结果将是:

isEqual(o1, o2) => true
isEqual(o2, o4) => true
isEqual(o3, o5) => true

请注意,isEqual是不可传递的,即在上述情况List(o1, o2, o4) List(o3, o5) 可能不等于o1,即使它们属于同一子列表。

2 个答案:

答案 0 :(得分:0)

您的问题等同于查找图表的所有连接组件的问题。

首先要做的是,将列表转换为图形G(V,E),其中V代表顶点,E代表边缘:

V = list
E = {(o1,o2) for all o1,o2 in list| o1.Equals(o2)}

之后使DFS找到所有组件

WHILE-EXISTS unvisted node in G DO
     component[i] = DFS(G)
END

当然是Graphs本身的组件。 组件是您要查找的列表,组件中的顶点是列表的元素。

对于您的示例,图表看起来像这样

enter image description here

注意:由于您必须比较每个对象,因此会话将采用O(n ^ 2)。 要找到所有组件,将需要O(n)。因此该算法具有O(n ^ 2)

的渐近运行时
  

回答您问题中的评论

     

由于您的问题转换为此图形问题似乎是正确的,   我很确定这是不可能的。如果将其视为图形,则只需检查每个节点是否与其他节点连接。在找到一个相等的节点后,你也无法停止,因为你可能会找到另一个相等的节点,并且通过停止,你将拆分连接的组件。

答案 1 :(得分:0)

您可以使用Disjoint set union算法查找所有连接的组件。然后打印列表。下面代码的时间复杂度是O(NlogN)。 weighted_union减少了联合到logN的时间复杂度。因此,如果我在最坏的情况下执行N次联合,则需要NlogN。

#include <bits/stdc++.h>
using namespace std;

int Arr[100], size[100];

int root (int i)
{
    while(Arr[ i ] != i)
    {
        Arr[ i ] = Arr[ Arr[ i ] ] ; 
        i = Arr[ i ]; 
    }
    return i;
}

void weighted_union(int A,int B)
{
    int root_A = root(A);
    int root_B = root(B);
    if(size[root_A] < size[root_B ])
    {
        Arr[ root_A ] = Arr[root_B];
        size[root_B] += size[root_A];
    }
    else
    {
        Arr[ root_B ] = Arr[root_A];
        size[root_A] += size[root_B];
    }
}

void initialize( int N)
{
    for(int i = 0;i<N;i++)
    {
        Arr[ i ] = i ;
        size[ i ] = 1;
    }
}

int main() {
    // your code goes here
    initialize(6);
    weighted_union(1,2);
    weighted_union(2,4);
    weighted_union(3,5);


    map<int, vector<int> >m;
    for (int i=1;i<=5;i++) {
        if(m.find(Arr[i])!=m.end()){
            vector<int> x = m[Arr[i]];
            x.push_back(i);
            m[Arr[i]] = x;
        } else {
            vector<int> x;
            x.push_back(i);
            m[Arr[i]]=x;
        }
    }

    for (std::map<int,vector<int> >::iterator it=m.begin(); it!=m.end(); ++it) {
        vector<int> x = it->second;
        for(int j=0;j<x.size();++j) {
            cout<<x[j]<<" ";
        }
        cout<<endl;
    }

    return 0;
}

您可以在此处找到解决方案的链接:http://ideone.com/vsT9Jh

相关问题