对数组进行排序并将所有重复的元素移动到结束

时间:2016-08-22 16:40:16

标签: algorithm sorting data-structures

我在最近的采访中遇到过这个问题。

给出了一个数组,我需要对数组进行排序,所有重复元素应该在最后。

实施例: 输入:{7,4,2,3,3,5,3,11,9,2}

自2& 3是它们应该在数组末尾出现的重复元素。

输出:{4,5,7,9,11,2,2,3,3,3}

我可以自由使用任何其他数据结构。没有限制。

5 个答案:

答案 0 :(得分:2)

containsPoint

您将对数组进行排序,以便重复值形成补丁。然后,您将数组分配给唯一值数组和重复值数组,并将它们打印出来。

第三行CREATE_ARRAY repeated, unique SORT inputArray ADD MINIMAL_POSSIBLE_VALUE TO inputArray TRAVERSE inputArray i=index (from 2nd element to last): IF inputArray[i-1] == inputArray[i]: 2X: ADD inputArray[i] TO repeated i++ WHILE i < LENGTH(inputArray) - 1 and inputArray[i-1] == inputArray[i]: ADD inputArray[i] TO repeated i++ ELSE: ADD inputArray[i-1] TO unique PRINT MERGED(unique, repeated) 只是在数组中添加一个永不打印的虚拟元素,但会为你节省一些IF语句。

&#13;
&#13;
ADD MINIMAL_POSSIBLE_VALUE TO inputArray
&#13;
// algorithm
function algorithm(input) {
  input.sort(function(a, b) { return a - b });
  input.push(Number.MIN_VAL);
  var repeated = [], unique = [];
  for (var i = 1; i < input.length; i++) {
    if (input[i - 1] == input[i]) {
      repeated.push(input[i], input[i]);
      i++;
      while (i < input.length - 1 && input[i - 1] == input[i]) {
        repeated.push(input[i]);
        i++;
      }
    } else {
      unique.push(input[i - 1]);
    }
  }
  return unique.concat(repeated);
}

// driver
inputBox = document.getElementById('input-box');
outputBox = document.getElementById("output-box");
inputBox.addEventListener("keyup", function() {
  outputBox.innerHTML = algorithm(inputBox.value.split(/[\s,]+/).map(Number));
});
&#13;
&#13;
&#13;

答案 1 :(得分:0)

使用List

的排序方法解决C#问题
        static void Main(string[] args)
    {
        List<int> list = new List<int> { 7, 4, 2, 3, 3, 5, 3, 11, 9, 2, 5 };

        List<int> tmp = new List<int> { };
        List<int> rep = new List<int> {};

        //sorting the list
        list.Sort();

        for (var i = 0; i < list.Count(); i++) 
        {
            int cantidad = list.LastIndexOf(list[i]) - list.IndexOf(list[i]);
            if ( cantidad != 0)
            {
                //found repetitions
                rep.AddRange(list.GetRange(list.IndexOf(list[i]), cantidad + 1));
                i += cantidad;
            }
            else tmp.Add(list[i]);
        }
        tmp.AddRange(rep);

        foreach (int data in tmp)
            Console.WriteLine(data);

        Console.ReadLine();
    }

手动排序C#的解决方案

        static void Main(string[] args)
    {
        List<int> list = new List<int> { 7, 4, 2, 3, 3, 5, 3, 11, 9, 2 };

        List<int> tmp = new List<int> {};
        List<int> rep = new List<int> {};

        foreach (int data in list)
        {
            if (tmp.Count() > 0)
            {
                int posicion = -1;
                bool bandera = false;
                for (var i=0; i < tmp.Count(); i++)
                {
                    //searching a repetition
                    if (tmp[i] == data)
                    {
                        tmp.RemoveAt(i);
                        //adding to the repeated list at the end or in a determined position
                        for (var j = 0; j < rep.Count(); i++)
                        {
                            if (rep[j] > data)
                            {
                                bandera = true;
                                rep.Insert(j, data); //the one that was deleted
                                rep.Insert(j, data); //the one at the original list
                                break;
                            }
                        }
                        if (!bandera)
                        {
                            bandera = true;
                            rep.Add(data); //the one that was deleted
                            rep.Add(data); //the one at the original list
                        }
                        break;
                    }
                    //saving the position to be inserted
                    if (tmp[i] > data)
                    {
                        posicion = i;
                        break;
                    }
                }
                //was not a repetition
                if (!bandera)
                {
                    bool banderaRep = false;
                    //searching in the repeated list
                    for (var i = 0; i < rep.Count(); i++)
                    {
                        if (rep[i] == data)
                        {
                            banderaRep = true;
                            rep.Insert(i, data);
                            break;
                        }
                    }
                    //was not in the repeated list
                    if (!banderaRep)
                    {
                        if (posicion == -1)
                            tmp.Add(data);
                        else
                            tmp.Insert(posicion, data);
                    }
                }
            }
            else
                tmp.Add(data);
        }
        //join
        tmp.AddRange(rep);

        foreach (int data in tmp)
            Console.WriteLine(data);

        Console.ReadLine();
    }

答案 2 :(得分:0)

使用地图数据结构的解决方案,不是一个非常有效的解决方案,但它仍然有效:

1&GT;遍历地图中数字的向量计数频率
2 - ;迭代地图(元素将按排序顺序)推动向量中的唯一元素和另一向量中的重复元素
3 GT;推送已排序数组中的重复元素

C ++中的代码

vector<int> sortUnique(const vector<int> & nums) {

// Step 1
map<int, int> numFreq;
for (auto it : nums) {
    if (numFreq.count(it) == 0) {
        numFreq[it] = 1;
    }
    else {
        numFreq[it]++;
    }
}

// Step 2
vector<int> sorted;
sorted.reserve(nums.size());
vector<int> repeated;
repeated.reserve(nums.size());
for (auto it : numFreq) {
    if (it.second == 1) {
        sorted.push_back(it.first);
    }
    else {
        for (int i = 0; i < it.second; i++) {
            repeated.push_back(it.first);
        }
    }
}
// Push repeated elements at the end
for (auto it : repeated) {
    sorted.push_back(it);
}
return sorted;
}

答案 3 :(得分:0)

您可以使用带有关联计数的值字典来执行此操作。你没有指定语言,所以我会给你一些伪代码。

注意这不会导致排序输出。

首先,扫描数组并创建值和字典词典:

dict = create new dictionary
for each item in array
    if dict contains item
        increase count for that item in the dictionary
    else
        add item to dictionary with count of 1

现在创建两个索引:一个从0开始,另一个在(array.length - 1)。对于字典中的每个项目,如果是单个项目,请将其写入数组的前面。否则在数组后面写入count项。像这样:

frontIndex = 0
backIndex = array.Length - 1
for each item in dictionary
    if item.count == 1
        array[frontIndex] = item
        frontIndex = frontIndex + 1
    else
       for i = 0 to item.Count-1
           array[backIndex-i] = item
       backIndex = backIndex - item.Count

构建字典的时间是O(n),O(n)重新填充数组。额外的空间是O(n)。

答案 4 :(得分:0)

我将使用Swift 3(beta 3)来描述您的问题的高级实现。

let list = [7,4,2,3,3,5,3,11,9,2]
let countedSet = NSCountedSet(array: list)
let singles = list.filter { countedSet.count(for: $0) == 1 }
let duplicates = list.filter { countedSet.count(for: $0) > 1 }
let res = singles.sorted() + duplicates.sorted()

第2行

这个类创建一个索引,它将每个值与它的出现次数相关联。

第3行和第4行

这里我正在过滤原始数组。我只将singles的值放入duplicates次,并将singles的值放入duplicates,然后再显示一次。

第5行

最后,我对delugeapt-get install deluged进行了排序,并将它们连接起来