递归删除数组中的元素

时间:2011-04-01 19:02:22

标签: algorithm

给定n个元素的数组,删除任何相邻的相邻元素对。重复此操作,直到没有更多相邻的对要移除;这将是最后一个数组。

例如1 2 2 3 4应返回数组1 3 4. 请注意数组不需要排序。

同时检查此测试用例:1,2,2,3,4,4,3,5 o / p应为1,5。 (2,2)和(4,4)被移除,然后(3,3)在移除(4,4)后变得相邻

9 个答案:

答案 0 :(得分:1)

每次删除一对元素时,您还需要查看是否生成了另一对要删除的元素。

该算法应该从该观察中自然地遵循。

答案 1 :(得分:1)

在Python中:

>>> l=[1,2,2,3,4,4,3,5]
>>> [x for x in l if not l.count(x) > 1]
[1, 5]

这将删除列表中出现多次的所有整数。对于您的示例,这是一个正确的结果,但我认为您确实想要说明不同的内容。我想你是在说:

list:=(an unsorted list of integers)
while adjacent_pairs(list) is True:
    remove_adjacent_pairs(list)

再一次,在Python中:

#!/usr/bin/env python

def dedupe_adjacent(l):
    for i in xrange(len(l) - 1, 0, -1):
        if l[i] == l[i-1]:
            del l[i-1:i+1]
            return True

    return False

def process_list(l):
    print "input list: ",l
    i=1
    while(dedupe_adjacent(l)):
        print "   loop ",i,":",l
        i+=1

    print "processed list=",l    
    print 

process_list([1,2,2,3,4,4,3,5])
process_list([1,2,2,3,4,4,6,3,5])

输出:

input list:  [1, 2, 2, 3, 4, 4, 3, 5]
   loop  1 : [1, 2, 2, 3, 3, 5]
   loop  2 : [1, 2, 2, 5]
   loop  3 : [1, 5]
processed list= [1, 5]

input list:  [1, 2, 2, 3, 4, 4, 6, 3, 5]
   loop  1 : [1, 2, 2, 3, 6, 3, 5]
   loop  2 : [1, 3, 6, 3, 5]
processed list= [1, 3, 6, 3, 5]

答案 2 :(得分:0)

这是基于编辑问题的基于堆栈的算法。

// pseudo code, not tested
void RemoveDupp(vector<int> & vin, vector<int> & vout)
{
    int i = 0, int j = -1;
    vout.resize(vin.size());

    while (i < vin.size())
    {
        if (j == -1 || vout[j] != vin[i])
            vout[++j] = vin[i++]; //push
        else
            j--, i++;             //pop
    }
    vout.resize(j + 1);
}

答案 3 :(得分:0)

以下内容:

function compress(arr) {
    var prev, res = [];
    for (var i in arr) {
        if (i == 0 || (arr[i] != arr[i - 1]))
            res.push(arr[i]);
    }
    return res;
}
compress([1, 2, 2, 3, 3, 3, 3, 4, 3, 3, 5, 6, 7, 8, 8]);

返回:

[1, 2, 3, 4, 3, 5, 6, 7, 8]

另外(JavaScript 1.6解决方案):

[1, 2, 2, 3, 3, 3, 3, 4, 3, 3, 5, 6, 7, 8, 8].filter(function(el, i, arr) {
    return i == 0 || (el != arr[i - 1]);
})

修改:多次删除数组中显示的任何项目都需要不同的解决方案:

function dedup(arr) {
    var res = [], seen = {};
    for (var i in arr)
        seen[arr[i]] = seen[arr[i]] ? ++seen[arr[i]] : 1;
    for (var j in arr) {
        if (seen[arr[j]] == 1)
            res.push(arr[j]);
    }
    return res;
}

以下内容:

dedup([1, 2, 2, 3, 4, 4, 3, 5]);

产地:

[1, 5]

答案 4 :(得分:0)

以下Python 3代码将从列表(数组)中删除重复项。它通过从开始到结束扫描数组并将目标元素与更大的元素进行比较来实现。如果它们是相同的,则将它们移除。如果元素指针未指向0,则将其减1以捕获嵌套对。如果两个比较元素不同,则指针递增。

我确信有更多的pythonic方法可以从列表中删除两个相邻的元素,但我是Python的新手并且尚未想到这一点。此外,您还想删除print(indx, SampleArray)声明 - 我将其留在那里,让您跟踪下面输出列表中的进度。

# Algorithm to remove duplicates in a semi-sorted list

def CompressArray(SampleArray):
    indx=0

    while(indx < len(SampleArray)-1):
        print(indx, SampleArray)
        if(SampleArray[indx]==SampleArray[indx+1]):
            del(SampleArray[indx])
            del(SampleArray[indx])
            if(indx>0):
                indx-=1
        else:
            indx+=1
    return SampleArray

以下是:

的示例运行
  • [1,2,3,3,4]
  • [1,2,3,3,4,4,3,5]
  • [1,2,3,3,3,3,3,3,3,5,5,7,8,8]
  • [1,2,3,3,4,6,7,7,6,4,3,8,8,5,9,10,10,9,11]
  • [1,1,2,3,3,2,4,5,6,5,5,7,8,8,7,4,9]

================================
0 [1, 2, 2, 3, 4]
1 [1, 2, 2, 3, 4]
0 [1, 3, 4]
1 [1, 3, 4]
[1, 3, 4]
================================
0 [1, 2, 2, 3, 4, 4, 3, 5]
1 [1, 2, 2, 3, 4, 4, 3, 5]
0 [1, 3, 4, 4, 3, 5]
1 [1, 3, 4, 4, 3, 5]
2 [1, 3, 4, 4, 3, 5]
1 [1, 3, 3, 5]
0 [1, 5]
[1, 5]
================================
0 [1, 2, 2, 3, 3, 3, 3, 4, 3, 3, 5, 6, 7, 8, 8]
1 [1, 2, 2, 3, 3, 3, 3, 4, 3, 3, 5, 6, 7, 8, 8]
0 [1, 3, 3, 3, 3, 4, 3, 3, 5, 6, 7, 8, 8]
1 [1, 3, 3, 3, 3, 4, 3, 3, 5, 6, 7, 8, 8]
0 [1, 3, 3, 4, 3, 3, 5, 6, 7, 8, 8]
1 [1, 3, 3, 4, 3, 3, 5, 6, 7, 8, 8]
0 [1, 4, 3, 3, 5, 6, 7, 8, 8]
1 [1, 4, 3, 3, 5, 6, 7, 8, 8]
2 [1, 4, 3, 3, 5, 6, 7, 8, 8]
1 [1, 4, 5, 6, 7, 8, 8]
2 [1, 4, 5, 6, 7, 8, 8]
3 [1, 4, 5, 6, 7, 8, 8]
4 [1, 4, 5, 6, 7, 8, 8]
5 [1, 4, 5, 6, 7, 8, 8]
[1, 4, 5, 6, 7]
================================
0 [1, 2, 2, 3, 4, 6, 7, 7, 6, 4, 3, 8, 8, 5, 9, 10, 10, 9, 11]
1 [1, 2, 2, 3, 4, 6, 7, 7, 6, 4, 3, 8, 8, 5, 9, 10, 10, 9, 11]
0 [1, 3, 4, 6, 7, 7, 6, 4, 3, 8, 8, 5, 9, 10, 10, 9, 11]
1 [1, 3, 4, 6, 7, 7, 6, 4, 3, 8, 8, 5, 9, 10, 10, 9, 11]
2 [1, 3, 4, 6, 7, 7, 6, 4, 3, 8, 8, 5, 9, 10, 10, 9, 11]
3 [1, 3, 4, 6, 7, 7, 6, 4, 3, 8, 8, 5, 9, 10, 10, 9, 11]
4 [1, 3, 4, 6, 7, 7, 6, 4, 3, 8, 8, 5, 9, 10, 10, 9, 11]
3 [1, 3, 4, 6, 6, 4, 3, 8, 8, 5, 9, 10, 10, 9, 11]
2 [1, 3, 4, 4, 3, 8, 8, 5, 9, 10, 10, 9, 11]
1 [1, 3, 3, 8, 8, 5, 9, 10, 10, 9, 11]
0 [1, 8, 8, 5, 9, 10, 10, 9, 11]
1 [1, 8, 8, 5, 9, 10, 10, 9, 11]
0 [1, 5, 9, 10, 10, 9, 11]
1 [1, 5, 9, 10, 10, 9, 11]
2 [1, 5, 9, 10, 10, 9, 11]
3 [1, 5, 9, 10, 10, 9, 11]
2 [1, 5, 9, 9, 11]
1 [1, 5, 11]
[1, 5, 11]
================================
0 [1, 1, 2, 3, 3, 2, 4, 5, 6, 6, 5, 7, 8, 8, 7, 4, 9]
0 [2, 3, 3, 2, 4, 5, 6, 6, 5, 7, 8, 8, 7, 4, 9]
1 [2, 3, 3, 2, 4, 5, 6, 6, 5, 7, 8, 8, 7, 4, 9]
0 [2, 2, 4, 5, 6, 6, 5, 7, 8, 8, 7, 4, 9]
0 [4, 5, 6, 6, 5, 7, 8, 8, 7, 4, 9]
1 [4, 5, 6, 6, 5, 7, 8, 8, 7, 4, 9]
2 [4, 5, 6, 6, 5, 7, 8, 8, 7, 4, 9]
1 [4, 5, 5, 7, 8, 8, 7, 4, 9]
0 [4, 7, 8, 8, 7, 4, 9]
1 [4, 7, 8, 8, 7, 4, 9]
2 [4, 7, 8, 8, 7, 4, 9]
1 [4, 7, 7, 4, 9]
0 [4, 4, 9]
[9]
================================

答案 5 :(得分:0)

我在Java中有一个解决方案。您需要在Java中的String类中使用replaceAll方法。您可以使用常规的移除来删除这些相邻的冗余字符:

public class MyString {
  public static void main(String[] args) {

    String str = "12234435";

    while(!str.replaceAll("(\\w)\\1+", "").equalsIgnoreCase(str))
      str = str.replaceAll("(\\w)\\1+", "");

    System.out.println(str);
  }
}

您可以找到如何提供正则表达式here

答案 6 :(得分:0)

我会:

  1. 对数组进行排序。
  2. 从数组的开头,直到你在数组的最后一个元素处:
    1. `count` =计算array [i]元素的数量。
    2. 如果`count`&gt;
    3. 删除数组的第一个`count`元素1。

答案 7 :(得分:0)

我喜欢Java,但功能性解决方案应该在这个网站上获得更多时间 在Haskell中,按照问题的方式做事:

compress lst = if (length lst == length b) then lst else (compress b) where
    b = helper lst
    helper [] = []
    helper [x] = [x]
    helper (x:y:xs) = if (x == y) then (helper xs) else (x:helper (y:xs))

你可以在O(n)时间内解决这个问题,虽然它有点复杂

compress' lst = reverse (helper [] lst) where
    helper xs [] = xs
    helper [] (x:xs) = helper [x] xs
    helper (a:as) (x:xs)
        | a == x = helper as xs
        | otherwise = helper (x:a:as) xs

答案 8 :(得分:0)

我认为我们可以使用堆栈来检查相邻的重复元素。 扫描阵列。对于每个新元素,如果它等于堆栈中的顶部元素,则将其删除并从堆栈中弹出顶部元素。否则,将其推入堆栈。