1. 程式人生 > 其它 >陣列如何實現O(1)的刪除元素

陣列如何實現O(1)的刪除元素

使用以下資料結構:

  • 動態陣列儲存元素值
  • 雜湊表儲存儲存值到索引的對映。

刪除任意索引元素需要線性時間,這裡的解決方案是總是刪除最後一個元素。

  • 將要刪除元素和最後一個元素交換。
  • 將最後一個元素刪除。
type RandomizedSet struct {
	// 儲存元素的值
	nums []int
	// 記錄每個元素對應在 nums 中的索引
	valToIndex map[int]int
}

// 構造方法
func Constructor() RandomizedSet {
	return RandomizedSet{
		nums:       []int{},
		valToIndex: map[int]int{},
	}
}

// 如果 val 不存在集合中,則插入並返回 true,否則直接返回 false
func (this *RandomizedSet) Insert(val int) bool {
	// 若 val 已存在,不用再插入
	if _, ok := this.valToIndex[val]; ok {
		return false
	}
	// 若 val 不存在,插入到 nums 尾部,
	// 並記錄 val 對應的索引值
	this.nums = append(this.nums, val)
	this.valToIndex[val] = len(this.nums) - 1
	return true
}

// 如果 val 在集合中,則刪除並返回 true,否則直接返回 false
func (this *RandomizedSet) Remove(val int) bool {
	// 若 val 不存在,不用再刪除
	if _, ok := this.valToIndex[val]; !ok {
		return false
	}
	// 拿到待刪除 val 的索引
	index := this.valToIndex[val]
	// 最後一個元素的索引
	lastIndex := len(this.nums) - 1
	// 將最後一個元素對應的索引修改為 index
	this.valToIndex[this.nums[lastIndex]] = index
	// 交換 val 和最後一個元素 (將 val 索引位置設為最後一個值也可)
	this.nums[index], this.nums[lastIndex] = this.nums[lastIndex], this.nums[index] //this.nums[index] = this.nums[lastIndex]
	// 將陣列中最後一個值 val 刪除
	this.nums = this.nums[0 : len(this.nums)-1]
	// 刪除元素 val 對應的索引
	delete(this.valToIndex, val)
	return true
}

// 從集合中等概率地隨機獲得一個元素
func (this *RandomizedSet) GetRandom() int {
	// 隨機獲取 nums 中的一個元素
	return this.nums[rand.Intn(len(this.nums))]
}