Удаление второго такого же элемента массива

У меня есть массив: int[] array = { 1055, 2, 29, 8, 7, 15, 29, 8, 22, 6, 29 }; В нем встречается два одинаковых элемента - 8. Как я могу удалить вторую восьмерку? (нужен массив вида:{ 1055, 2, 29, 8, 7, 15, 29, 22, 6, 29 } Понимаю, что требуется метод Find(который у меня есть) и Delete(который я без понятия как написать). Готовый код с некоторыми функциями см. ниже. Заранее спасибо!

class Program
{
    class Seznam {
        public int data;
        public Seznam next;
    }
    static void Main(string[] args)
    {
        int[] pole = { 1055, 2, 29, 8, 7, 15, 29, 8, 22, 6, 29 };
        Seznam s = ConvertToArray(pole);
        Print(s);
        int i = Count(pole);
        Console.WriteLine("Count: {0}", i);

    } 
    static Seznam Delete(Seznam s, ???) {

    }
    static Seznam Find(Seznam s, int n) {
        Seznam akt = s
        while (akt != null)
        {
            if (akt.data == n) return akt;
            akt = akt.next;
        }
        return null;
    }
    static int Count(int[] array) {
        int count = 0;

        for (int i = 0; i < array.Length; i++) {
            
            for (int j = i; j < array.Length - 1; j++) {
                if (array[i] == array[j + 1]) {
                    count++;
                    break;
                }
            }
        }
        return count;
    }
    static Seznam Create(int n) {
        Seznam vys = new Seznam();
        vys.data = n;
        vys.next = null;
        return vys;
    }
    static Seznam ConvertToArray(int[] arr) {
        int i;
        Seznam vys, akt, tmp;
        if (arr.Length == 0) return null;
        vys = akt = null;
        for (i = 0; i < arr.Length; i++) {
            tmp = Create(arr[i]);
            if (vys == null) vys = akt = tmp;
            else akt = akt.next = tmp;
        }
        return vys;
    }
    static Seznam Find(Seznam s, int n) {
        Seznam akt = s;
        while (akt != null) {
            if (akt.data == n) return akt;
            akt = akt.next;
        }
        return null;
    }
    static void Print(Seznam s) {
        Seznam akt;
        for (akt = s; akt != null; akt = akt.next)
                Console.Write(akt.data + " ");
            Console.WriteLine();
    }
}

Ответы (1 шт):

Автор решения: A K

Ну, в основе будет лежать алгоритм сдвига ячеек:

public int[] ShiftDown(int[] source, int from)
{
    var result = source;
    
    for (int i = from; i < source.Length -1; i++)
    {
        result[i] = result[i + 1];
    }
    
    return result;
}

Типа, на ваших данных будет что-то типа:

int[] array = { 1055, 2, 29, 8, 7, 15, 29, 8, 22, 6, 29 };

var result = ShiftDown(array, 7);

Результат "до" - "после":

введите сюда описание изображения

При этом важно понимать что такое Size и Capacity массива, видно, что второй массив содержит мусор в конце (в тренировочных задачах на Leetcode иногда просят занулить эти ячейки, чаще же просто просят вернуть из метода новый size с in place модификациями прямо в исходном массиве без возврата нового), а по-хорошему надо отрезать от массива первые 10 элементов.

Как это сделать - я бы лично сделал через linq-функцию Take. Второй вариант - через Array.Copy (он кстати и самый быстрый AFAIK).

В целом же вам никто не запрещает сделать метод, который скопирует сначала первую часть массива до восьмёрки, пропустить восьмёрку и дальше скопировать остаток массива:

public int[] ShiftDown(int[] source, int from)
{
    var result = new int[source.Length - 1];
    
    for (int i = 0; i < from; i++)
    {
        result[i] = source[i];
    }
    
    for (int i = from; i < source.Length -1; i++)
    {
        result[i] = source[i + 1];
    }
    
    return result;
}

(Этот метод нужно будет вызывать и для 8 и для 29 - они тоже дублируются)

Поскольку задание явно учебно-тренировочное - вам виднее какие подходы запрещены, а какие разрешены. Могу только указать, что все ваши алгоритмы будут заведомо неэффективнее чем вариант с HashSet<int> - т.к. вам будет нужно N ^ 2 раз обойти массив в поисках дублей.

→ Ссылка