Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用递归从两个链表中查找公共节点_Java_Algorithm_Recursion - Fatal编程技术网

Java 使用递归从两个链表中查找公共节点

Java 使用递归从两个链表中查找公共节点,java,algorithm,recursion,Java,Algorithm,Recursion,我必须编写一个方法,使用递归返回一个链表,其中包含两个链表共有的所有节点,没有循环 比如说, 第一个列表是2->5->7->10 第二个列表是2->4->8->10 将返回的列表为2->10 这件事我做不到。。我一直在想的是递归地检查第一个列表的每个值和第二个列表的每个值,但第二个列表每次都会被一个节点剪切,我无法比较第一个列表和第二个列表中的下一个值。我希望这是有意义的 有人能帮忙吗?这个问题取决于约束条件 最简单、最简单的解决方案是,如果您有两个大小为n的元素,则迭代一个列表,并将其与第二个

我必须编写一个方法,使用递归返回一个链表,其中包含两个链表共有的所有节点,没有循环

比如说,

第一个列表是2->5->7->10

第二个列表是2->4->8->10

将返回的列表为2->10

这件事我做不到。。我一直在想的是递归地检查第一个列表的每个值和第二个列表的每个值,但第二个列表每次都会被一个节点剪切,我无法比较第一个列表和第二个列表中的下一个值。我希望这是有意义的


有人能帮忙吗?

这个问题取决于约束条件

最简单、最简单的解决方案是,如果您有两个大小为
n
的元素,则迭代一个列表,并将其与第二个列表中的每个项目进行比较

溶液:O(n2)

但你当然可以做得更好

现在,如果您有可用的
HashSet
(或其他近O(1))数据结构,那么您可以这样做:

迭代一个列表。将每个元素添加到集合中。迭代第二个列表。如果元素在集合中,则将其添加到结果列表中


解决方案:O(n)

此问题取决于约束条件

最简单、最简单的解决方案是,如果您有两个大小为
n
的元素,则迭代一个列表,并将其与第二个列表中的每个项目进行比较

溶液:O(n2)

但你当然可以做得更好

现在,如果您有可用的
HashSet
(或其他近O(1))数据结构,那么您可以这样做:

迭代一个列表。将每个元素添加到集合中。迭代第二个列表。如果元素在集合中,则将其添加到结果列表中


解决方案:O(n)

如果对每个列表中的值进行排序,则此问题仅具有权重。如果是这种情况,那么将递归地(在伪代码中)查找重复项

节点合并(节点n1、节点n2){
如果n1==null或n2==null
返回空值
如果n1.value==n2.value,则为ELSE
节点dupNode(n1.值);
dupNode.next=合并(n1.next,n2.next);
返回dup节点;
如果n1.值小于n2.值,则为ELSE
返回合并(n1.next,n2)
其他的
返回合并(n1,n2.下一步)
}

给定长度
L1
L2
的列表,这将在
O(L1+L2)
中合并它们。它通过为重复项创建新节点,以非破坏性的方式执行此操作。如果您愿意,您可以轻松地将其修改为从其中一个列表中“偷取”。

如果每个列表中的值都已排序,则此问题仅具有权重。如果是这种情况,那么将递归地(在伪代码中)查找重复项

节点合并(节点n1、节点n2){
如果n1==null或n2==null
返回空值
如果n1.value==n2.value,则为ELSE
节点dupNode(n1.值);
dupNode.next=合并(n1.next,n2.next);
返回dup节点;
如果n1.值小于n2.值,则为ELSE
返回合并(n1.next,n2)
其他的
返回合并(n1,n2.下一步)
}

给定长度
L1
L2
的列表,这将在
O(L1+L2)
中合并它们。它通过为重复项创建新节点,以非破坏性的方式执行此操作。如果愿意,您可以轻松地将其修改为从其中一个列表中“窃取”。

如果您不关心重复项,那么使用Set的内置retainal()方法是一个简单的解决方案

  List<T> list1 = ...; // The smaller list
  List<T> list2 = ...; 

  ...
  final Set<T> s1 = new HashSet<T>(list1);
  s1.retainAll(list2); 
  // Try s1.retainAll(new HashSet<T>(list2)); if the lists are really bug

  final List<T> solution = new LinkedList(s1);
列表列表1=…;//小名单
列表2=。。。;
...
最终集s1=新哈希集(列表1);
s1.保留(列表2);
//尝试s1.retainal(新的HashSet(list2));如果列表真的是bug
最终列表解决方案=新的LinkedList(s1);

如果您不关心重复项,那么使用Set的内置retainal()方法是一个简单的解决方案

  List<T> list1 = ...; // The smaller list
  List<T> list2 = ...; 

  ...
  final Set<T> s1 = new HashSet<T>(list1);
  s1.retainAll(list2); 
  // Try s1.retainAll(new HashSet<T>(list2)); if the lists are really bug

  final List<T> solution = new LinkedList(s1);
列表列表1=…;//小名单
列表2=。。。;
...
最终集s1=新哈希集(列表1);
s1.保留(列表2);
//尝试s1.retainal(新的HashSet(list2));如果列表真的是bug
最终列表解决方案=新的LinkedList(s1);

有很多方法可以解释这个问题。我们是在寻找由列表表示的集合的交集,还是在寻找最长的公共子序列?列表总是排序的吗

在我的递归解决方案中,我假设我们正在寻找一些最长的子序列,并且我不假设关于项目顺序的任何内容:

private static <T> List<T> longestCommonSubseq(List<T> a, int indA, List<T> b, int indB){
    if (indA == a.size() || indB == b.size())
        return Collections.emptyList();

    T itemA = a.get(indA);
    T itemB = b.get(indB);

    List<T> res;
    if (itemA.equals(itemB)){
        res = new ArrayList<T>();
        res.add(itemA);
        res.addAll(longestCommonSubseq(a, indA+1, b, indB+1));
    }else{
        List<T> opt1 = longestCommonSubseq(a, indA+1, b, indB);
        List<T> opt2 = longestCommonSubseq(a, indA, b, indB+1);
        if (opt1.size()>opt2.size())
            res = opt1;
        else
            res = opt2;
    }
    return res;
}

public static <T> List<T> longestCommonSubseq(List<T> a, List<T> b){
    return longestCommonSubseq(a,0,b,0);
}
private static List longestCommonSubseq(列表a、int-indA、列表b、int-indB){
如果(indA==a.size()| | indB==b.size())
返回集合。emptyList();
T itemA=a.get(indA);
T itemB=b.get(indB);
列表资源;
如果(项目a等于(项目b)){
res=新的ArrayList();
决议增补(第a项);
res.addAll(longestCommonSubseq(a,indA+1,b,indB+1));
}否则{
列表opt1=最长的公共资源(a,indA+1,b,indB);
列表opt2=最长的公共资源量(a,indA,b,indB+1);
if(opt1.size()>opt2.size())
res=opt1;
其他的
res=opt2;
}
返回res;
}
公共静态列表longestCommonSubseq(列表a、列表b){
返回最长的等式(a,0,b,0);
}

注意:为了简单起见,在我的解决方案中,列表应该是随机访问的(例如ArrayList)。

有很多方法可以解释这个问题。我们是在寻找由列表表示的集合的交集,还是在寻找最长的公共子序列?列表总是排序的吗

在我的递归解决方案中,我假设我们正在寻找一些最长的子序列,并且我不假设关于项目顺序的任何内容:

private static <T> List<T> longestCommonSubseq(List<T> a, int indA, List<T> b, int indB){
    if (indA == a.size() || indB == b.size())
        return Collections.emptyList();

    T itemA = a.get(indA);
    T itemB = b.get(indB);

    List<T> res;
    if (itemA.equals(itemB)){
        res = new ArrayList<T>();
        res.add(itemA);
        res.addAll(longestCommonSubseq(a, indA+1, b, indB+1));
    }else{
        List<T> opt1 = longestCommonSubseq(a, indA+1, b, indB);
        List<T> opt2 = longestCommonSubseq(a, indA, b, indB+1);
        if (opt1.size()>opt2.size())
            res = opt1;
        else
            res = opt2;
    }
    return res;
}

public static <T> List<T> longestCommonSubseq(List<T> a, List<T> b){
    return longestCommonSubseq(a,0,b,0);
}
private static List longestCommonSubseq(列表a、int-indA、列表b、int-indB){
如果(indA==a.size()| | indB==b.size())
返回集合。emptyList();
T itemA=a.get(indA);
T itemB=b.get(indB);
列表资源;
如果(项目a等于(项目b)){
res=新的ArrayList();
决议增补(第a项);
res.addAll(最长)
struct node *sortedIntersect(struct node *a, struct node *b)
{
    /* base case */
    if (a == NULL || b == NULL)
        return NULL;

    /* If both lists are non-empty */

    /* advance the smaller list and call recursively */
    if (a->data < b->data)
        return sortedIntersect(a->next, b);

    if (a->data > b->data)
        return sortedIntersect(a, b->next);

    // Below lines are executed only when a->data == b->data
    struct node *temp = (struct node *)malloc(sizeof(struct node));
    temp->data = a->data;

    /* advance both lists and call recursively */
    temp->next = sortedIntersect(a->next, b->next);
    return temp;
}