# [algorithm learning] sword finger Offer II 042. Number of recent requests (Java / C / C + + / Python / go / trust)

Posted by omegared on Tue, 02 Nov 2021 16:02:57 +0100

Welcome[ 👍 [like][ ⭐ Collection][ 📝 [comments]~
It's not hard to give up, but it must be cool to insist~
I hope all of us can make a little progress every day~
This paper consists of The white hat of the second leader https://le-yi.blog.csdn.net/ Blog originality~

# Sword finger Offer II 042. Recent requests:

Write a RecentCounter class to calculate the most recent requests within a specific time range.

• RecentCounter() initializes the counter, and the number of requests is 0.
• int ping(int t) adds a new request at time t, where T represents a time in milliseconds and returns the number of all requests (including new requests) that have occurred in the past 3000 milliseconds. Specifically, returns the number of requests that occurred within [t-3000, t].

Ensure that each call to ping uses a larger t value than before.

# Example 1

```Input:
inputs = ["RecentCounter", "ping", "ping", "ping", "ping"]
inputs = [[], [1], [100], [3001], [3002]]
Output:
[null, 1, 2, 3, 3]

Explanation:
RecentCounter recentCounter = new RecentCounter();
recentCounter.ping(1);     // requests = [1], range [- 2999,1], return 1
recentCounter.ping(100);   // requests = [1, 100], range [- 2900100], return 2
recentCounter.ping(3001);  // requests = [1, 100, 3001], the range is [13001], and 3 is returned
recentCounter.ping(3002);  // requests = [1, 100, 3001, 3002], the range is [23002], and 3 is returned
```

# Tips

• 1 <= t <= 109
• Ensure that the t value used for each ping call is strictly incremented
• The ping method can be called up to 104 times

# analysis

• The second leader thinks that this algorithm problem has relatively high degrees of freedom.
• As stipulated in Article 2 of the prompt, the T value used for each Ping call is strictly increased, so the queue can be used. If the difference between the current T and the latest t is more than 3000, it can be cleared. Just go out of the queue in order. There are only 3000 elements in the queue at most, that is, the worst of each Ping is no more than 3000 times out of the queue, The value left by the queue is exactly the return value of the ping method.
• As stipulated in Article 3 of the prompt, the maximum number of ping calls has been known. If a randomly accessible data structure is used, binary search can also be used. The time complexity will be better than queuing in order. However, if the number of ping is not certain, it is better to use a queue.

# Problem solution

## java

The built-in binary search is not used because it is not a negative number and is not the value we want.

```class RecentCounter {
private int[] q;
private int tail;

public RecentCounter() {
q = new int[10000];
}

public int ping(int t) {
q[tail++] = t;
}

private int binarySearch(int[] a, int fromIndex, int toIndex, int key) {
int low  = fromIndex;
int high = toIndex - 1;

while (low <= high) {
int mid    = (low + high) >>> 1;
int midVal = a[mid];

if (midVal < key)
low = mid + 1;
else if (midVal > key)
high = mid - 1;
else
return mid; // key found
}
}
}
```

## c

```typedef struct {
int *q;
int tail;
} RecentCounter;

RecentCounter *recentCounterCreate() {
RecentCounter *recentCounter = (RecentCounter *) malloc(sizeof(RecentCounter));
recentCounter->q = (int *) malloc(sizeof(int) * 10000);
recentCounter->tail = 0;
return recentCounter;
}

int binarySearch(int *a, int fromIndex, int toIndex, int key) {
int low = fromIndex;
int high = toIndex - 1;

while (low <= high) {
int mid = (low + high) >> 1;
int midVal = a[mid];

if (midVal < key)
low = mid + 1;
else if (midVal > key)
high = mid - 1;
else
return mid; // key found
}
}

int recentCounterPing(RecentCounter *obj, int t) {
obj->q[obj->tail++] = t;
}

void recentCounterFree(RecentCounter *obj) {
free(obj->q);
free(obj);
}
```

## c++

```class RecentCounter {
private:
vector<int> q;
public:
RecentCounter() {
}

int binarySearch(vector<int>& a, int fromIndex, int toIndex, int key) {
int low = fromIndex;
int high = toIndex - 1;

while (low <= high) {
int mid = (low + high) >> 1;
int midVal = a[mid];

if (midVal < key)
low = mid + 1;
else if (midVal > key)
high = mid - 1;
else
return mid; // key found
}
}

int ping(int t) {
q.push_back(t);
}
};
```

## python

python is the most concise this time. It mainly has binary search that can be used directly.

```class RecentCounter:

def __init__(self):
self.q = []

def ping(self, t: int) -> int:
self.q.append(t)
```

## go

```type RecentCounter struct {
q    []int
}

func Constructor() RecentCounter {
return RecentCounter{[]int{}, 0}
}

func (this *RecentCounter) Ping(t int) int {
this.q = append(this.q, t)
}

func binarySearch(a []int, fromIndex int, toIndex int, key int) int {
low := fromIndex
high := toIndex - 1

for low <= high {
mid := (low + high) >> 1
midVal := a[mid]

if midVal < key {
low = mid + 1
} else if midVal > key {
high = mid - 1
} else {
return mid // key found
}
}
}
```

## rust

```struct RecentCounter {
q: Vec<i32>,
}

/**
* `&self` means the method takes an immutable reference.
* If you need a mutable reference, change it to `&mut self` instead.
*/
impl RecentCounter {
fn new() -> Self {
RecentCounter { q: Vec::new(), head: 0 }
}

fn ping(&mut self, t: i32) -> i32 {
self.q.push(t);
}

fn binarySearch(a: &Vec<i32>, fromIndex: i32, toIndex: i32, key: i32) -> i32 {
let mut low = fromIndex;
let mut high = toIndex - 1;

while low <= high {
let mid = (low + high) >> 1;
let midVal = a[mid as usize];

if midVal < key {
low = mid + 1;
} else if midVal > key {
high = mid - 1;
} else {
return mid; // key found
}
}