Veri yapısı: ekleme, kaldırma, içeren, rastgele eleman alma, tümü O (1) 'de


96

Bu problem bana bir röportajda verildi. Nasıl cevap verirdin?

O (1) zamanında aşağıdaki işlemleri sunan bir veri yapısı tasarlayın:

  • eklemek
  • Kaldırmak
  • içerir
  • rastgele eleman al

Veri türlerine ek kısıtlamalar getirebilir miyiz? kopya yok gibi
Sanjeevakumar Hiremath

Elbette, yineleme yok, java veya c # gibi bir dilde yerleşik veri yapılarını bile kullanabilirsiniz.
guildner

1
Yeniden: sıralı / sırasız spesifikasyon olmadığına dikkat edin
Charles Duffy

7
Bu yazının yanıtlandığını biliyorum, ancak bana rastgele bir öğe almak yerine o (1) rastgele erişim sağlamanızı isteseler daha mantıklı olur.
ramsinb

Bunun için doğru çözümü buldunuz mu?
Balaji Boggaram Ramanarayan

Yanıtlar:


145

Bir hashtable H ve bir dizi A'dan oluşan bir veri yapısını düşünün. Hashtable anahtarları veri yapısındaki öğelerdir ve değerler dizideki konumlarıdır.

  1. ekle (değer): değeri diziye ekleyin ve A'daki dizini i olsun. H [değer] = i ayarlayın.
  2. remove (değer): A'daki değeri içeren hücreyi A'daki son elemanla değiştireceğiz, d dizisinde m indisindeki son eleman olsun. ben H [değer], kaldırılacak değer dizisindeki dizin olsun. A [i] = d, H [d] = i ayarlayın, dizinin boyutunu bir küçültün ve H'den değeri kaldırın.
  3. içerir (değer): H.içerir (değer) döndür
  4. getRandomElement (): let r = random (A'nın mevcut boyutu). dönüş A [r].

Dizinin boyutunun otomatik olarak artması gerektiğinden, bir eleman eklemek için O (1) 'i amorti edecek, ama sanırım sorun değil.


Bu, sahip olduğuma yakın, ancak öğelerin anahtar olarak kullanılmasını özledim .... Yakın olduğumu biliyordum, ama bu gerçekten kafama vuruyor!
guildner

Bu soruyu bir Google telefon ekranından aldım ve aynı çözüme takılıp kaldıktan sonra biraz uğraştım. Bir uygulamayı biraz bozdum ve ikinci telefon ekranına atadım.
Andrey Talnikov

ADiziye değer ekleyin: O (1) nasıl?
Balaji Boggaram Ramanarayan

4
@aamadmi - Java'da olması gerektiğini tahmin ediyorum. Sözde kodda, içerir çok iyi çalışmalıdır :)
r0u1i

4
Dizi neden gerekli, neden hashmap kullanamıyoruz?
Ankit Zalani

22

O (1) araması, karma bir veri yapısını ifade eder .

Kıyasla:

  • O (1) O (N) aramalı ekle / sil, bağlantılı bir liste anlamına gelir.
  • O (1) ekleme, O (N) silme ve O (N) arama, dizi destekli bir liste anlamına gelir
  • O (logN) ekle / sil / arama bir ağaç veya yığın anlamına gelir.

Bu bir başlangıç, ama son gereksinim ne olacak? Hashing uygulanmış bir veri yapısından rastgele bir öğe (veri yapısındaki her öğe için eşit olasılıkla) elde edebilir misiniz?
guildner

1
@ lag1980, sanırım şunları yapabilirsiniz:hashtable.get((int)(Math.random()*hashtable.size()));
CMR

3
Hmmm, böyle bir öğeyi almanıza izin veren herhangi bir hashtable bilmiyorum ve eğer varsa, bunun sabit zamanlı bir işlem olacağını hayal edemiyorum. Her iki durumda da yanıldığımın kanıtlanmasıyla ilgilenirim.
guildner

@ lag1980 ... bunu sabit zamanda kolaylıkla yapabilirsiniz Clojure'un vektörleri "sabit zaman" dır - log32 (N) olası N değerleri donanımınız tarafından, olası en büyük log32 () değeri şu şekilde sınırlandırıldığında ... 7 gibi, etkin bir şekilde sabit zaman.
Charles Duffy

"Dizi destekli liste" derken şunu kastediyorsunuz: dizi?
Hengameh

5

Bundan hoşlanmayabilirsiniz, çünkü muhtemelen akıllı bir çözüm arıyorlar, ancak bazen silahlarınıza bağlı kalmak için para ödüyor ... Bir hash tablosu, gereksinimleri zaten karşılamaktadır - muhtemelen genel olarak her şeyden daha iyidir (tabii ki amortize edilmiş sabit olarak da olsa) zaman ve diğer çözümlerden farklı tavizlerle).

Zor olan gereksinim, "rastgele öğe" seçimidir: bir karma tabloda, böyle bir öğeyi taramanız veya araştırmanız gerekir.

Kapalı hashing / açık adresleme için, herhangi bir paketin işgal edilme şansı size() / capacity(), ancak çok önemli bir şekilde, bu genellikle bir hash-tablo uygulamasıyla sabit bir çarpımsal aralıkta tutulur (örneğin, tablo, örneğin 1.2x kadar mevcut içeriğinden daha büyük tutulabilir. performans / bellek ayarına bağlı olarak ~ 10x). Bu, ortalama olarak, kabın toplam boyutundan tamamen bağımsız olarak, 1,2 ila 10 kova aramayı bekleyebileceğimiz anlamına gelir; amortize edilmiş O (1).

İki basit yaklaşım hayal edebiliyorum (ve çok daha karmaşık olanı):

  • rastgele bir gruptan doğrusal olarak arama

    • Eğer: - "D --AC ----- B" boş / değer tutma ala kepçeler dikkate edebilirsiniz ilk "rastgele" seçim adil B tercih edilme artık ihtimalini vardı çünkü, B iyilik olsa olduğunu söylemek diğer öğelerden daha iyidir, ancak aynı değerleri kullanarak tekrarlanan "rastgele" seçimler yapıyorsanız, açıkça B'nin tekrar tekrar tercih edilmesi istenmeyebilir (sorudaki hiçbir şey olasılıkları bile gerektirmez)
  • dolu bir paket bulana kadar rastgele paketleri tekrar tekrar deneyin

    • "sadece" kapasite () / size () ziyaret edilen ortalama paketler (yukarıdaki gibi) - ancak pratik açıdan daha pahalıdır çünkü rastgele sayı üretimi nispeten pahalıdır ve sonsuz derecede olası olmayan en kötü durum davranışı ise sonsuz derecede kötüdür ...
      • Daha hızlı bir uzlaşma, başlangıçta rastgele seçilen gruptan önceden oluşturulmuş rastgele ofsetlerin bir listesini kullanarak bunları paket sayımına% olarak ayırmak olacaktır.

Harika bir çözüm değil, ancak yine de her zaman ikinci bir dizin dizisini korumanın bellek ve performans ek yüklerinden daha iyi bir genel uzlaşma olabilir.


3

En iyi çözüm muhtemelen hash table + dizisidir, gerçekten hızlı ve deterministiktir.

Ancak en düşük puanlı cevap (sadece bir karma tablo kullanın!) Aslında harika!

  • Yeniden hashing içeren karma tablosu veya yeni grup seçimi (yani, grup başına bir öğe, bağlantılı liste yok)
  • getRandom () boşalana kadar art arda rastgele bir paket seçmeye çalışır.
  • bir başarısızlık olarak, belki getRandom (), N (öğe sayısı) başarısız denemeden sonra, [0, N-1] 'de rastgele bir i indeksi seçer ve ardından karma tablosundan doğrusal olarak geçer ve # i-inci öğeyi seçer .

İnsanlar "olası sonsuz döngüler" yüzünden bundan hoşlanmayabilir ve çok zeki insanların da bu tepkiyi gördüğünü gördüm, ama bu yanlış! Sonsuz ihtimal olaylar sadece yok olur.

Sözde rastgele kaynağınızın - bu belirli davranış için tespit edilmesi zor olmayan - iyi davranışını ve hash tablolarının her zaman en az% 20 dolu olduğunu varsayarsak, şunu görmek kolaydır:

Olacak asla getRandom () 1000'den fazla kere denemek gerektiğini olur. Sadece asla . Gerçekte, böyle bir olayın olasılığı 0.8 ^ 1000'dir, bu da 10 ^ -97'dir - bu yüzden, bir milyarda bir şansın bir kez olması için bunu 10 ^ 88 kez tekrar etmemiz gerekir. Bu program, Güneş ölünceye kadar insanlığın tüm bilgisayarlarında tam zamanlı olarak çalışıyor olsa bile, bu asla olmayacak.


1
Sürekli olarak değeri olan rastgele bir kova seçmeyi seçerseniz, en kötü durum nasıl olur da rastgele bir öğe seçerken O (1) 'e yol açar
Balaji Boggaram Ramanarayan

@ user1147505 - bu numarayı nereden aldın: "0.8 ^ 1000"?
Hengameh

Buna nasıl ulaştınız: "karma tablolar her zaman en az% 20 dolu"
Hengameh

Rastgele bir kova seçebileceğiniz yöntemi yazabilir misiniz?
Hengameh

3

Bu Soru için iki Veri Yapısı kullanacağım

  • HashMap
  • ArrayList / Array / Double LinkedList.

Adımlar: -

  1. Ekleme: - X'in HashMap'te zaten mevcut olup olmadığını kontrol edin - Zaman karmaşıklığı O (1). Mevcut değilse ArrayList'in sonuna ekleyin - Zaman karmaşıklığı O (1). HashMap'e ayrıca anahtar olarak x ve değer olarak son Dizin ekleyin - Zaman karmaşıklığı O (1).
  2. Kaldır: - HashMap - Zaman karmaşıklığı O (1) 'de X'in mevcut olup olmadığını kontrol edin. Varsa, dizinini bulun ve HashMap --Time karmaşıklığı O (1) 'den kaldırın. Bu öğeyi ArrayList'teki son öğe ile takas edin ve son öğe olan --Time karmaşıklığı O (1) 'i kaldırın. HashMap --Time karmaşıklığı O (1) 'de son Eleman'ın dizinini güncelleyin.
  3. GetRandom: - 0'dan ArrayList'in son dizinine Rastgele sayı üretin. ArrayList öğesini rastgele oluşturulan dizinde döndürür - Zaman karmaşıklığı O (1).
  4. Arama: - Anahtar olarak x için HashMap'e bakın. --Zaman karmaşıklığı O (1).

Kod: -

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;


public class JavaApplication1 {

    public static void main(String args[]){
       Scanner sc = new Scanner(System.in);
        ArrayList<Integer> al =new ArrayList<Integer>();
        HashMap<Integer,Integer> mp = new HashMap<Integer,Integer>();  
        while(true){
            System.out.println("**menu**");
            System.out.println("1.insert");
            System.out.println("2.remove");
            System.out.println("3.search");
            System.out.println("4.rendom");
            int ch = sc.nextInt();
            switch(ch){
                case 1 : System.out.println("Enter the Element ");
                        int a = sc.nextInt();
                        if(mp.containsKey(a)){
                            System.out.println("Element is already present ");
                        }
                        else{
                            al.add(a);
                            mp.put(a, al.size()-1);

                        }
                        break;
                case 2 : System.out.println("Enter the Element Which u want to remove");
                        a = sc.nextInt();
                        if(mp.containsKey(a)){

                            int size = al.size();
                            int index = mp.get(a);

                            int last = al.get(size-1);
                            Collections.swap(al, index,  size-1);

                            al.remove(size-1);
                            mp.put(last, index);

                            System.out.println("Data Deleted");

                        }
                        else{
                            System.out.println("Data Not found");
                        }
                        break;
                case 3 : System.out.println("Enter the Element to Search");
                        a = sc.nextInt();
                        if(mp.containsKey(a)){
                            System.out.println(mp.get(a));
                        }
                        else{
                            System.out.println("Data Not Found");
                        }
                        break;
                case 4 : Random rm = new Random();
                        int index = rm.nextInt(al.size());
                        System.out.println(al.get(index));
                        break;

            }
        }
    }

}

- Zaman karmaşıklığı O (1). - Uzay karmaşıklığı O (N).


1

İşte bir süre önce aynı soru sorulduğunda bulduğum bu soruna bir C # çözümü. Diğer standart .NET arabirimleriyle birlikte Ekle, Kaldır, İçerir ve Rastgele uygular. Bir röportaj sırasında bu kadar ayrıntılı bir şekilde uygulamanız gerekmeyeceğinden değil, ancak bakmak için somut bir çözüme sahip olmak güzel ...

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

/// <summary>
/// This class represents an unordered bag of items with the
/// the capability to get a random item.  All operations are O(1).
/// </summary>
/// <typeparam name="T">The type of the item.</typeparam>
public class Bag<T> : ICollection<T>, IEnumerable<T>, ICollection, IEnumerable
{
    private Dictionary<T, int> index;
    private List<T> items;
    private Random rand;
    private object syncRoot;

    /// <summary>
    /// Initializes a new instance of the <see cref="Bag&lt;T&gt;"/> class.
    /// </summary>
    public Bag()
        : this(0)
    {
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="Bag&lt;T&gt;"/> class.
    /// </summary>
    /// <param name="capacity">The capacity.</param>
    public Bag(int capacity)
    {
        this.index = new Dictionary<T, int>(capacity);
        this.items = new List<T>(capacity);
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="Bag&lt;T&gt;"/> class.
    /// </summary>
    /// <param name="collection">The collection.</param>
    public Bag(IEnumerable<T> collection)
    {
        this.items = new List<T>(collection);
        this.index = this.items
            .Select((value, index) => new { value, index })
            .ToDictionary(pair => pair.value, pair => pair.index);
    }

    /// <summary>
    /// Get random item from bag.
    /// </summary>
    /// <returns>Random item from bag.</returns>
    /// <exception cref="System.InvalidOperationException">
    /// The bag is empty.
    /// </exception>
    public T Random()
    {
        if (this.items.Count == 0)
        {
            throw new InvalidOperationException();
        }

        if (this.rand == null)
        {
            this.rand = new Random();
        }

        int randomIndex = this.rand.Next(0, this.items.Count);
        return this.items[randomIndex];
    }

    /// <summary>
    /// Adds the specified item.
    /// </summary>
    /// <param name="item">The item.</param>
    public void Add(T item)
    {
        this.index.Add(item, this.items.Count);
        this.items.Add(item);
    }

    /// <summary>
    /// Removes the specified item.
    /// </summary>
    /// <param name="item">The item.</param>
    /// <returns></returns>
    public bool Remove(T item)
    {
        // Replace index of value to remove with last item in values list
        int keyIndex = this.index[item];
        T lastItem = this.items[this.items.Count - 1];
        this.items[keyIndex] = lastItem;

        // Update index in dictionary for last item that was just moved
        this.index[lastItem] = keyIndex;

        // Remove old value
        this.index.Remove(item);
        this.items.RemoveAt(this.items.Count - 1);

        return true;
    }

    /// <inheritdoc />
    public bool Contains(T item)
    {
        return this.index.ContainsKey(item);
    }

    /// <inheritdoc />
    public void Clear()
    {
        this.index.Clear();
        this.items.Clear();
    }

    /// <inheritdoc />
    public int Count
    {
        get { return this.items.Count; }
    }

    /// <inheritdoc />
    public void CopyTo(T[] array, int arrayIndex)
    {
        this.items.CopyTo(array, arrayIndex);
    }

    /// <inheritdoc />
    public bool IsReadOnly
    {
        get { return false; }
    }

    /// <inheritdoc />
    public IEnumerator<T> GetEnumerator()
    {
        foreach (var value in this.items)
        {
            yield return value;
        }
    }

    /// <inheritdoc />
    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }

    /// <inheritdoc />
    public void CopyTo(Array array, int index)
    {
        this.CopyTo(array as T[], index);
    }

    /// <inheritdoc />
    public bool IsSynchronized
    {
        get { return false; }
    }

    /// <inheritdoc />
    public object SyncRoot
    {
        get
        {
            if (this.syncRoot == null)
            {
                Interlocked.CompareExchange<object>(
                    ref this.syncRoot,
                    new object(),
                    null);
            }

            return this.syncRoot;

        }
    }
}

Yinelenen numaralarınız varsa bunun işe yarayacağından emin değilim.
AlexIIP

@ Guildner, sorunun yorumlarında kopya olmadığını varsaydığını söylediğinden, kopyaları işlemez. Bir kopya eklenirse ArgumentException"Aynı anahtara sahip bir öğe zaten eklenmiştir" mesajıyla birlikte. atılır (temeldeki dizin Sözlüğünden).
Scott Lerch

1

İşlemleri Θ (1) sürede desteklemek için hashing kullanabiliriz.

insert (x) 1) Bir hash map araması yaparak x'in zaten mevcut olup olmadığını kontrol edin. 2) Mevcut değilse, dizinin sonuna ekleyin. 3) Ayrıca hash tablosuna x anahtar olarak ve son dizi indeksi indeks olarak eklenir.

remove (x) 1) Bir karma harita araması yaparak x'in mevcut olup olmadığını kontrol edin. 2) Varsa, dizinini bulun ve karma haritadan kaldırın. 3) Dizideki son elemanı bu elemanla değiştirin ve son elemanı kaldırın. Takas yapılır çünkü son eleman O (1) zamanında kaldırılabilir. 4) Hash haritasındaki son elemanın indeksini güncelleyin.

getRandom () 1) 0'dan son dizine kadar rastgele bir sayı üretir. 2) Rastgele oluşturulmuş dizindeki dizi öğesini döndürür.

search (x) Hash haritasında x için bir arama yapın.


1

Bu çok eski olsa da, C ++ 'da cevap olmadığına göre, işte benim iki sentim.

#include <vector>
#include <unordered_map>
#include <stdlib.h>

template <typename T> class bucket{
    int size;
    std::vector<T> v;
    std::unordered_map<T, int> m;
public:
    bucket(){
        size = 0;
        std::vector<T>* v = new std::vector<T>();
        std::unordered_map<T, int>* m = new std::unordered_map<T, int>();
    }
    void insert(const T& item){
        //prevent insertion of duplicates
        if(m.find(item) != m.end()){
            exit(-1);
        }
        v.push_back(item);
        m.emplace(item, size);
        size++;

    }
    void remove(const T& item){
        //exits if the item is not present in the list
        if(m[item] == -1){
            exit(-1);
        }else if(m.find(item) == m.end()){
            exit(-1);
        }

        int idx = m[item];
        m[v.back()] = idx;
        T itm = v[idx];
        v.insert(v.begin()+idx, v.back());
        v.erase(v.begin()+idx+1);
        v.insert(v.begin()+size, itm);
        v.erase(v.begin()+size);
        m[item] = -1;
        v.pop_back();
        size--;

    }

     T& getRandom(){
      int idx = rand()%size;
      return v[idx];

     }

     bool lookup(const T& item){
       if(m.find(item) == m.end()) return false;
       return true;

     }
    //method to check that remove has worked
    void print(){
        for(auto it = v.begin(); it != v.end(); it++){
            std::cout<<*it<<" ";
        }
    }
};

İşte çözümü test etmek için bir müşteri kodu parçası.

int main() {

    bucket<char>* b = new bucket<char>();
    b->insert('d');
    b->insert('k');
    b->insert('l');
    b->insert('h');
    b->insert('j');
    b->insert('z');
    b->insert('p');

    std::cout<<b->random()<<std::endl;
    b->print();
    std::cout<<std::endl;
    b->remove('h');
    b->print();

    return 0;
}

0

C # 3.0 + .NET Framework 4'te, genel Dictionary<TKey,TValue>bir Hashtable'dan bile daha iyidir çünkü System.Linquzantı yöntemini ElementAt(), KeyValuePair<TKey,TValue>öğelerin depolandığı temeldeki dinamik diziye dizin oluşturmak için kullanabilirsiniz :

using System.Linq;

Random _generator = new Random((int)DateTime.Now.Ticks);

Dictionary<string,object> _elements = new Dictionary<string,object>();

....

Public object GetRandom()
{
     return _elements.ElementAt(_generator.Next(_elements.Count)).Value;
}

Bununla birlikte, bildiğim kadarıyla, bir Hashtable (veya onun Sözlük nesli) bu soruna gerçek bir çözüm değildir çünkü Put () sadece O (1) amorti edilebilir, gerçek O (1) değil, çünkü O (N ) dinamik yeniden boyutlandırma sınırında.

Bu soruna gerçek bir çözüm var mı? Tek düşünebildiğim, bir Sözlük / Hashtable başlangıç ​​kapasitesini, ihtiyaç duymayı beklediğinizin ötesinde bir büyüklük sıralaması belirlerseniz, O (1) işlemleri elde edersiniz çünkü asla yeniden boyutlandırmanız gerekmez.


Karma tablonun ne olduğu konusunda çok katıysanız, O (N) yeniden boyutlandırma kaçınılmazdır. Bazı uygulamalar, yeniden boyutlandırma maliyetini düşürmekten ödün verir - örneğin, iki katı boyut eklerken mevcut tabloyu koruyarak veya mevcut tabloyu yerinde yeniden boyutlandırmaya çalışarak (sayfa sınırlarında sanal adres alanını ve tablo boyutlarını dikkatlice düzenledikten sonra, bu nedenle hayır yeni / malloc mem yerine bellek haritalarını gerektirebilen kopyalama gereklidir), daha sonra daha küçük alana geri dönmeden önce (daha sıkı bir yerinde modelde) öğe göç mantığı ile yeni daha büyük alanda arama yapmak gerekir.
Tony Delroy

0

Anon'a katılıyorum. Eşit adaletle rastgele bir öğe elde etmenin gerekli olduğu son gereksinim dışında, diğer tüm gereksinimler yalnızca tek bir Hash tabanlı DS kullanılarak ele alınabilir. Bunun için Java'da HashSet'i seçeceğim. Bir elemanın hash kodunun modulosu bana O (1) zamanında temeldeki dizinin indeks numarasını verecektir. Bunu ekleme, kaldırma ve içeren işlemler için kullanabilirim.


0

Bunu Java HashSet kullanarak yapamaz mıyız? Varsayılan olarak O (1) 'de insert, del, search sağlar. GetRandom için yine de rasgele davranışlar veren Set yineleyicisini kullanabiliriz. Geri kalan öğeler hakkında endişelenmeden setteki ilk öğeyi yineleyebiliriz

public void getRandom(){
    Iterator<integer> sitr = s.iterator();
    Integer x = sitr.next();    
    return x;
}

0
/* Java program to design a data structure that support folloiwng operations
   in Theta(n) time
   a) Insert
   b) Delete
   c) Search
   d) getRandom */
import java.util.*;

// class to represent the required data structure
class MyDS
{
   ArrayList<Integer> arr;   // A resizable array

   // A hash where keys are array elements and vlaues are
   // indexes in arr[]
   HashMap<Integer, Integer>  hash;

   // Constructor (creates arr[] and hash)
   public MyDS()
   {
       arr = new ArrayList<Integer>();
       hash = new HashMap<Integer, Integer>();
   }

   // A Theta(1) function to add an element to MyDS
   // data structure
   void add(int x)
   {
      // If ekement is already present, then noting to do
      if (hash.get(x) != null)
          return;

      // Else put element at the end of arr[]
      int s = arr.size();
      arr.add(x);

      // And put in hash also
      hash.put(x, s);
   }

   // A Theta(1) function to remove an element from MyDS
   // data structure
   void remove(int x)
   {
       // Check if element is present
       Integer index = hash.get(x);
       if (index == null)
          return;

       // If present, then remove element from hash
       hash.remove(x);

       // Swap element with last element so that remove from
       // arr[] can be done in O(1) time
       int size = arr.size();
       Integer last = arr.get(size-1);
       Collections.swap(arr, index,  size-1);

       // Remove last element (This is O(1))
       arr.remove(size-1);

       // Update hash table for new index of last element
       hash.put(last, index);
    }

    // Returns a random element from MyDS
    int getRandom()
    {
       // Find a random index from 0 to size - 1
       Random rand = new Random();  // Choose a different seed
       int index = rand.nextInt(arr.size());

       // Return element at randomly picked index
       return arr.get(index);
    }

    // Returns index of element if element is present, otherwise null
    Integer search(int x)
    {
       return hash.get(x);
    }
}

// Driver class
class Main
{
    public static void main (String[] args)
    {
        MyDS ds = new MyDS();
        ds.add(10);
        ds.add(20);
        ds.add(30);
        ds.add(40);
        System.out.println(ds.search(30));
        ds.remove(20);
        ds.add(50);
        System.out.println(ds.search(50));
        System.out.println(ds.getRandom());`enter code here`
    }
}

-2

Rastgele eleman bulmak için neden epoch% arraysize kullanmıyoruz? Dizi boyutunu bulmak O (n) ama amortize edilmiş karmaşıklık O (1) olacaktır.


-3

Hash table ile ikili bağlantı listesini kullanabileceğimizi düşünüyorum. anahtar öğe olacak ve ilişkili değeri çift bağlantı listesindeki düğüm olacaktır.

  1. (H, E) ekleyin: düğümü çift bağlantı listesine ekleyin ve girişi H [E] = düğüm olarak yapın; O (1)
  2. sil (H, E): düğüm adresini H (E) ile al, bu düğümden bir öncekine git ve H (E) yi NULL yap, yani O (1)
  3. içerir (H, E) ve getRandom (H) açıkça O (1)

Bu mantıklı değil.
innosam
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.