Перемешать массив


Сложный уровень средний
Часто спрашивают в Амазонка Facebook Google Microsoft Oracle
массив Hash хеширования

Дан массив или набор, содержащий n элементов. Здесь элементы уникальны или нет повторения. Перемешать массив(или набор) номеров без дубликатов.

Пример

// Инициируем массив с наборами 2, 4, 3 и 1.

int [] nums = {2, 4, 3, 1};

Перемешать объект = новый Перемешать (числа);

// Перемешать массив [2, 4, 3, 1] и вернуть его результат. Любая перестановка [2, 4, 3, 1] должна быть возвращена с равной вероятностью, например [4, 2, 1, 3] object.shuffle ();

// Сбрасывает массив обратно в исходную конфигурацию массива, то есть [2, 4, 3, 1].

solution.reset ();

Мы можем сделать это, используя временную сложность O (n), используя две хэш-карты.

Структуры данных, используемые для перемешивания массива

Карта M (для хранения значения, индексная пара)

Карта K (для хранения значения, измененного индекса)

Вектор arr для хранения текущих элементов, присутствующих в массиве.

Например:

Перемешать массив

Алгоритм для функции конструктора

  1. Для каждого элемента, присутствующего в данном массиве nums:
    1. arr [i] = nums [i]
    2. вставьте пару значений ключа (nums [i], i) в K.
    3. вставьте пару значений ключа (nums [i], i) в M.

Алгоритм сброса ()

  1. Для каждой записи, присутствующей на карте M (итератор it):
    1. arr [it.second] = arr [it.first], обновить вектор исходными значениями.
  2. Возвращение обр.

Алгоритм перемешивания ()

  1. Выполните цикл от n до 0:
    1. Выберите случайный индекс (индекс) в диапазоне (0, n).
    2. Возьмите элемент, присутствующий в индексе, и замените его последним элементом, присутствующим в массиве.
    3. Обновите хеш-значения для элемента индекса и последнего элемента на карте K.
  2. Возвращение обр.

Реализация

Программа на C ++ для перемешивания массива

#include<bits/stdc++.h>
using namespace std;
class Shuffle {
public:
    vector<int> arr;
    unordered_map<int,int> m;
    unordered_map<int,int> k;
    Shuffle(vector<int>& nums) {
        for(int i=0;i<nums.size();i++){
            arr.push_back(nums[i]);
            m.insert({nums[i],i});
            k.insert({nums[i],i});
        }
    }
    /** Resets the array to its original configuration and return it. */
    vector<int> reset() {
        for(auto it:m){
            arr[it.second]=it.first;
        }
        return arr;
    }
    
    /** Returns a random shuffling of the array. */
    vector<int> shuffle() {
        int n=arr.size();
        while(n){
            int in=rand()%n;
            int index= k[arr[n-1]];
            k[arr[n-1]]=k[arr[in]];
            k[arr[in]]=index;
            swap(arr[in],arr[n-1]);
            n--;
        }
        return arr;
    }
};

int main()
{
    vector<int> nums = {2,3,4,1,5,6};
    Shuffle* obj = new Shuffle(nums);
    cout<<"Original array:\n";
    for(int i=0;i<nums.size();i++){
        cout<<nums[i]<<" ";
    }
    vector<int> _shuffle = obj->shuffle();
    cout<<"\nArray after shuffle:\n";
    for(int i=0;i<_shuffle.size();i++){
        cout<<_shuffle[i]<<" ";
    }
    vector<int> _reset = obj->reset();
    cout<<"\nArray after reset:\n";
    for(int i=0;i<_reset.size();i++){
        cout<<_reset[i]<<" ";
    }
    return 0;
}
Original array:
2 3 4 1 5 6 
Array after shuffle:
2 4 1 5 6 3 
Array after reset:
2 3 4 1 5 6 

Программа JAVA для перемешивания массива

import java.util.*;
class Shuffle {
    HashMap<Integer, Integer> m,k;
    int[] arr;

    public Shuffle(int[] nums) {
        m = new HashMap<>();
        k = new HashMap<>();
        int n=nums.length;
        arr = new int[n];
        for(int i=0;i<n;i++){
            arr[i]=nums[i];
            m.put(nums[i],i);
            k.put(nums[i],i);
        }
    }
    
    /** Resets the array to its original configuration and return it. */
    public int[] reset() {
        for(Map.Entry<Integer, Integer> it : m.entrySet()){
            arr[it.getValue()]=it.getKey();
        }
        return arr;
    }
    
    /** Returns a random shuffling of the array. */
    public int[] shuffle() {
        int n=arr.length;
        Random rand = new Random(); 
        while(n>0){
            int in=rand.nextInt(n);
            int index = k.get(arr[n-1]);
            k.put(arr[n-1],k.get(arr[in]));
            k.put(arr[in],index);
            int temp = arr[in];
            arr[in] = arr[n-1];
            arr[n-1] = temp;
            n--;
        }
        return arr;
    }
}
public class Main
{
  public static void main(String[] args) {
      int[] nums = {2,3,4,6};
        Shuffle obj = new Shuffle(nums);
        System.out.print("Original array:\n");
        for(int i=0;i<nums.length;i++){
            System.out.print(nums[i]+" ");
        }
        int[] _shuffle = obj.shuffle();
        System.out.print("\nArray after shuffle:\n");
        for(int i=0;i<_shuffle.length;i++){
            System.out.print(_shuffle[i]+" ");
        }
        int[] _reset = obj.reset();
        System.out.print("\nArray after reset:\n");
        for(int i=0;i<_reset.length;i++){
            System.out.print(_reset[i]+" ");
        }
  }
}
Original array:
2 3 4 6 1 0 1 0 
Array after shuffle:
4 6 2 3 
Array after reset:
2 3 4 6 

Анализ сложности для перемешивания массива

Сложность времени

O (n) all function, т.е. функция-конструктор, shuffle (), reset (), поскольку всем функциям требуется обход массива только один раз. Вот почему это приводит нас к линейной временной сложности.

Пространство сложности

O (n), нам нужны 2 вспомогательные хэш-карты размера n для хранения пары индексов значений.

дело