返回介绍

solution / 1700-1799 / 1756.Design Most Recently Used Queue / README_EN

发布于 2024-06-17 01:03:14 字数 8206 浏览 0 评论 0 收藏 0

1756. Design Most Recently Used Queue

中文文档

Description

Design a queue-like data structure that moves the most recently used element to the end of the queue.

Implement the MRUQueue class:

  • MRUQueue(int n) constructs the MRUQueue with n elements: [1,2,3,...,n].
  • int fetch(int k) moves the kth element (1-indexed) to the end of the queue and returns it.

 

Example 1:

Input:
["MRUQueue", "fetch", "fetch", "fetch", "fetch"]
[[8], [3], [5], [2], [8]]
Output:
[null, 3, 6, 2, 2]

Explanation:
MRUQueue mRUQueue = new MRUQueue(8); // Initializes the queue to [1,2,3,4,5,6,7,8].
mRUQueue.fetch(3); // Moves the 3rd element (3) to the end of the queue to become [1,2,4,5,6,7,8,3] and returns it.
mRUQueue.fetch(5); // Moves the 5th element (6) to the end of the queue to become [1,2,4,5,7,8,3,6] and returns it.
mRUQueue.fetch(2); // Moves the 2nd element (2) to the end of the queue to become [1,4,5,7,8,3,6,2] and returns it.
mRUQueue.fetch(8); // The 8th element (2) is already at the end of the queue so just return it.

 

Constraints:

  • 1 <= n <= 2000
  • 1 <= k <= n
  • At most 2000 calls will be made to fetch.

 

Follow up: Finding an O(n) algorithm per fetch is a bit easy. Can you find an algorithm with a better complexity for each fetch call?

Solutions

Solution 1

class MRUQueue:
  def __init__(self, n: int):
    self.q = list(range(1, n + 1))

  def fetch(self, k: int) -> int:
    ans = self.q[k - 1]
    self.q[k - 1 : k] = []
    self.q.append(ans)
    return ans


# Your MRUQueue object will be instantiated and called as such:
# obj = MRUQueue(n)
# param_1 = obj.fetch(k)
class BinaryIndexedTree {
  private int n;
  private int[] c;

  public BinaryIndexedTree(int n) {
    this.n = n;
    this.c = new int[n + 1];
  }

  public void update(int x, int v) {
    while (x <= n) {
      c[x] += v;
      x += x & -x;
    }
  }

  public int query(int x) {
    int s = 0;
    while (x > 0) {
      s += c[x];
      x -= x & -x;
    }
    return s;
  }
}

class MRUQueue {
  private int n;
  private int[] q;
  private BinaryIndexedTree tree;

  public MRUQueue(int n) {
    this.n = n;
    q = new int[n + 2010];
    for (int i = 1; i <= n; ++i) {
      q[i] = i;
    }
    tree = new BinaryIndexedTree(n + 2010);
  }

  public int fetch(int k) {
    int l = 1, r = n;
    while (l < r) {
      int mid = (l + r) >> 1;
      if (mid - tree.query(mid) >= k) {
        r = mid;
      } else {
        l = mid + 1;
      }
    }
    int x = q[l];
    q[++n] = x;
    tree.update(l, 1);
    return x;
  }
}

/**
 * Your MRUQueue object will be instantiated and called as such:
 * MRUQueue obj = new MRUQueue(n);
 * int param_1 = obj.fetch(k);
 */
class BinaryIndexedTree {
public:
  BinaryIndexedTree(int _n)
    : n(_n)
    , c(_n + 1) {}

  void update(int x, int delta) {
    while (x <= n) {
      c[x] += delta;
      x += x & -x;
    }
  }

  int query(int x) {
    int s = 0;
    while (x) {
      s += c[x];
      x -= x & -x;
    }
    return s;
  }

private:
  int n;
  vector<int> c;
};

class MRUQueue {
public:
  MRUQueue(int n) {
    q.resize(n + 1);
    iota(q.begin() + 1, q.end(), 1);
    tree = new BinaryIndexedTree(n + 2010);
  }

  int fetch(int k) {
    int l = 1, r = q.size();
    while (l < r) {
      int mid = (l + r) >> 1;
      if (mid - tree->query(mid) >= k) {
        r = mid;
      } else {
        l = mid + 1;
      }
    }
    int x = q[l];
    q.push_back(x);
    tree->update(l, 1);
    return x;
  }

private:
  vector<int> q;
  BinaryIndexedTree* tree;
};

/**
 * Your MRUQueue object will be instantiated and called as such:
 * MRUQueue* obj = new MRUQueue(n);
 * int param_1 = obj->fetch(k);
 */
type BinaryIndexedTree struct {
  n int
  c []int
}

func newBinaryIndexedTree(n int) *BinaryIndexedTree {
  c := make([]int, n+1)
  return &BinaryIndexedTree{n, c}
}

func (this *BinaryIndexedTree) update(x, delta int) {
  for x <= this.n {
    this.c[x] += delta
    x += x & -x
  }
}

func (this *BinaryIndexedTree) query(x int) int {
  s := 0
  for x > 0 {
    s += this.c[x]
    x -= x & -x
  }
  return s
}

type MRUQueue struct {
  q  []int
  tree *BinaryIndexedTree
}

func Constructor(n int) MRUQueue {
  q := make([]int, n+1)
  for i := 1; i <= n; i++ {
    q[i] = i
  }
  return MRUQueue{q, newBinaryIndexedTree(n + 2010)}
}

func (this *MRUQueue) Fetch(k int) int {
  l, r := 1, len(this.q)
  for l < r {
    mid := (l + r) >> 1
    if mid-this.tree.query(mid) >= k {
      r = mid
    } else {
      l = mid + 1
    }
  }
  x := this.q[l]
  this.q = append(this.q, x)
  this.tree.update(l, 1)
  return x
}

/**
 * Your MRUQueue object will be instantiated and called as such:
 * obj := Constructor(n);
 * param_1 := obj.Fetch(k);
 */
class BinaryIndexedTree {
  private n: number;
  private c: number[];

  constructor(n: number) {
    this.n = n;
    this.c = new Array(n + 1).fill(0);
  }

  public update(x: number, v: number): void {
    while (x <= this.n) {
      this.c[x] += v;
      x += x & -x;
    }
  }

  public query(x: number): number {
    let s = 0;
    while (x > 0) {
      s += this.c[x];
      x -= x & -x;
    }
    return s;
  }
}

class MRUQueue {
  private q: number[];
  private tree: BinaryIndexedTree;

  constructor(n: number) {
    this.q = new Array(n + 1);
    for (let i = 1; i <= n; ++i) {
      this.q[i] = i;
    }
    this.tree = new BinaryIndexedTree(n + 2010);
  }

  fetch(k: number): number {
    let l = 1;
    let r = this.q.length;
    while (l < r) {
      const mid = (l + r) >> 1;
      if (mid - this.tree.query(mid) >= k) {
        r = mid;
      } else {
        l = mid + 1;
      }
    }
    const x = this.q[l];
    this.q.push(x);
    this.tree.update(l, 1);
    return x;
  }
}

/**
 * Your MRUQueue object will be instantiated and called as such:
 * var obj = new MRUQueue(n)
 * var param_1 = obj.fetch(k)
 */

Solution 2

class BinaryIndexedTree:
  def __init__(self, n: int):
    self.n = n
    self.c = [0] * (n + 1)

  def update(self, x: int, v: int):
    while x <= self.n:
      self.c[x] += v
      x += x & -x

  def query(self, x: int) -> int:
    s = 0
    while x:
      s += self.c[x]
      x -= x & -x
    return s


class MRUQueue:
  def __init__(self, n: int):
    self.q = list(range(n + 1))
    self.tree = BinaryIndexedTree(n + 2010)

  def fetch(self, k: int) -> int:
    l, r = 1, len(self.q)
    while l < r:
      mid = (l + r) >> 1
      if mid - self.tree.query(mid) >= k:
        r = mid
      else:
        l = mid + 1
    x = self.q[l]
    self.q.append(x)
    self.tree.update(l, 1)
    return x


# Your MRUQueue object will be instantiated and called as such:
# obj = MRUQueue(n)
# param_1 = obj.fetch(k)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文