Skip to content

Commit

Permalink
feat: update solutions to lc problem: No.2241 (#3925)
Browse files Browse the repository at this point in the history
No.2241.Design an ATM Machine
  • Loading branch information
yanglbme authored Jan 5, 2025
1 parent 3b89cf8 commit fd7c89f
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 122 deletions.
85 changes: 45 additions & 40 deletions solution/2200-2299/2241.Design an ATM Machine/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,11 @@ atm.withdraw(550); // 返回 [0,1,0,0,1] ,机器会返回 1 张 $50 的

### 方法一:模拟

我们用一个数组 $d$ 记录钞票面额,用一个数组 $cnt$ 记录每种面额的钞票数量。
我们用一个数组 $\textit{d}$ 记录钞票面额,用一个数组 $\textit{cnt}$ 记录每种面额的钞票数量。

对于 `deposit` 操作,我们只需要将对应面额的钞票数量加上即可。时间复杂度 $O(1)$。

对于 `withdraw` 操作,我们从大到小枚举每种面额的钞票,取出尽可能多且不超过 $amount$ 的钞票,然后将 $amount$ 减去取出的钞票面额之和,如果最后 $amount$ 仍大于 $0$,说明无法取出 $amount$ 的钞票,返回 $-1$ 即可。否则,返回取出的钞票数量即可。时间复杂度 $O(1)$。
对于 `withdraw` 操作,我们从大到小枚举每种面额的钞票,取出尽可能多且不超过 $\textit{amount}$ 的钞票,然后将 $\textit{amount}$ 减去取出的钞票面额之和,如果最后 $\textit{amount}$ 仍大于 $0$,说明无法取出 $\textit{amount}$ 的钞票,返回 $-1$ 即可。否则,返回取出的钞票数量即可。时间复杂度 $O(1)$。

<!-- tabs:start -->

Expand All @@ -91,22 +91,23 @@ atm.withdraw(550); // 返回 [0,1,0,0,1] ,机器会返回 1 张 $50 的
```python
class ATM:
def __init__(self):
self.cnt = [0] * 5
self.d = [20, 50, 100, 200, 500]
self.m = len(self.d)
self.cnt = [0] * self.m

def deposit(self, banknotesCount: List[int]) -> None:
for i, v in enumerate(banknotesCount):
self.cnt[i] += v
for i, x in enumerate(banknotesCount):
self.cnt[i] += x

def withdraw(self, amount: int) -> List[int]:
ans = [0] * 5
for i in range(4, -1, -1):
ans = [0] * self.m
for i in reversed(range(self.m)):
ans[i] = min(amount // self.d[i], self.cnt[i])
amount -= ans[i] * self.d[i]
if amount > 0:
return [-1]
for i, v in enumerate(ans):
self.cnt[i] -= v
for i, x in enumerate(ans):
self.cnt[i] -= x
return ans


Expand All @@ -120,8 +121,9 @@ class ATM:

```java
class ATM {
private long[] cnt = new long[5];
private int[] d = {20, 50, 100, 200, 500};
private int m = d.length;
private long[] cnt = new long[5];

public ATM() {
}
Expand All @@ -133,15 +135,15 @@ class ATM {
}

public int[] withdraw(int amount) {
int[] ans = new int[5];
for (int i = 4; i >= 0; --i) {
int[] ans = new int[m];
for (int i = m - 1; i >= 0; --i) {
ans[i] = (int) Math.min(amount / d[i], cnt[i]);
amount -= ans[i] * d[i];
}
if (amount > 0) {
return new int[] {-1};
}
for (int i = 0; i < 5; ++i) {
for (int i = 0; i < m; ++i) {
cnt[i] -= ans[i];
}
return ans;
Expand Down Expand Up @@ -171,23 +173,24 @@ public:
}

vector<int> withdraw(int amount) {
vector<int> ans(5);
for (int i = 4; ~i; --i) {
vector<int> ans(m);
for (int i = m - 1; ~i; --i) {
ans[i] = min(1ll * amount / d[i], cnt[i]);
amount -= ans[i] * d[i];
}
if (amount > 0) {
return {-1};
}
for (int i = 0; i < 5; ++i) {
for (int i = 0; i < m; ++i) {
cnt[i] -= ans[i];
}
return ans;
}

private:
long long cnt[5] = {0};
int d[5] = {20, 50, 100, 200, 500};
static constexpr int d[5] = {20, 50, 100, 200, 500};
static constexpr int m = size(d);
long long cnt[m] = {0};
};

/**
Expand All @@ -201,32 +204,33 @@ private:
#### Go
```go
type ATM struct {
d [5]int
cnt [5]int
}
var d = [...]int{20, 50, 100, 200, 500}
const m = len(d)
type ATM [m]int
func Constructor() ATM {
return ATM{[5]int{20, 50, 100, 200, 500}, [5]int{}}
return ATM{}
}
func (this *ATM) Deposit(banknotesCount []int) {
for i, v := range banknotesCount {
this.cnt[i] += v
for i, x := range banknotesCount {
this[i] += x
}
}
func (this *ATM) Withdraw(amount int) []int {
ans := make([]int, 5)
for i := 4; i >= 0; i-- {
ans[i] = min(amount/this.d[i], this.cnt[i])
amount -= ans[i] * this.d[i]
ans := make([]int, m)
for i := m - 1; i >= 0; i-- {
ans[i] = min(amount/d[i], this[i])
amount -= ans[i] * d[i]
}
if amount > 0 {
return []int{-1}
}
for i, v := range ans {
this.cnt[i] -= v
for i, x := range ans {
this[i] -= x
}
return ans
}
Expand All @@ -242,31 +246,32 @@ func (this *ATM) Withdraw(amount int) []int {
#### TypeScript

```ts
const d: number[] = [20, 50, 100, 200, 500];
const m = d.length;

class ATM {
private cnt: number[];
private d: number[];

constructor() {
this.cnt = [0, 0, 0, 0, 0];
this.d = [20, 50, 100, 200, 500];
this.cnt = Array(m).fill(0);
}

deposit(banknotesCount: number[]): void {
for (let i = 0; i < banknotesCount.length; i++) {
for (let i = 0; i < banknotesCount.length; ++i) {
this.cnt[i] += banknotesCount[i];
}
}

withdraw(amount: number): number[] {
let ans = [0, 0, 0, 0, 0];
for (let i = 4; i >= 0; i--) {
ans[i] = Math.min(Math.floor(amount / this.d[i]), this.cnt[i]);
amount -= ans[i] * this.d[i];
const ans: number[] = Array(m).fill(0);
for (let i = m - 1; i >= 0; --i) {
ans[i] = Math.min(Math.floor(amount / d[i]), this.cnt[i]);
amount -= ans[i] * d[i];
}
if (amount > 0) {
return [-1];
}
for (let i = 0; i < ans.length; i++) {
for (let i = 0; i < m; ++i) {
this.cnt[i] -= ans[i];
}
return ans;
Expand Down
87 changes: 46 additions & 41 deletions solution/2200-2299/2241.Design an ATM Machine/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,11 @@ atm.withdraw(550); // Returns [0,1,0,0,1]. The machine uses 1 $50 banknot

### Solution 1: Simulation

We use an array $d$ to record the denominations of the bills and an array $cnt$ to record the number of bills for each denomination.
We use an array $\textit{d}$ to record the denominations of the bills and an array $\textit{cnt}$ to record the number of bills for each denomination.

For the `deposit` operation, we only need to add the number of bills for the corresponding denomination. The time complexity is $O(1)$.
For the `deposit` operation, we simply add the number of bills to the corresponding denomination. The time complexity is $O(1)$.

For the `withdraw` operation, we enumerate the bills from largest to smallest denomination, taking out as many bills as possible without exceeding the $amount$. Then, we subtract the total value of the withdrawn bills from $amount$. If $amount$ is still greater than $0$ at the end, it means it's not possible to withdraw the $amount$ with the available bills, and we return $-1$. Otherwise, we return the number of bills withdrawn. The time complexity is $O(1)$.
For the `withdraw` operation, we enumerate the bills from largest to smallest denomination, taking out as many bills as possible without exceeding $\textit{amount}$. We then subtract the total value of the withdrawn bills from $\textit{amount}$. If $\textit{amount}$ is still greater than $0$ at the end, it means we cannot withdraw the requested amount, and we return $-1$. Otherwise, we return the number of withdrawn bills. The time complexity is $O(1)$.

<!-- tabs:start -->

Expand All @@ -97,22 +97,23 @@ For the `withdraw` operation, we enumerate the bills from largest to smallest de
```python
class ATM:
def __init__(self):
self.cnt = [0] * 5
self.d = [20, 50, 100, 200, 500]
self.m = len(self.d)
self.cnt = [0] * self.m

def deposit(self, banknotesCount: List[int]) -> None:
for i, v in enumerate(banknotesCount):
self.cnt[i] += v
for i, x in enumerate(banknotesCount):
self.cnt[i] += x

def withdraw(self, amount: int) -> List[int]:
ans = [0] * 5
for i in range(4, -1, -1):
ans = [0] * self.m
for i in reversed(range(self.m)):
ans[i] = min(amount // self.d[i], self.cnt[i])
amount -= ans[i] * self.d[i]
if amount > 0:
return [-1]
for i, v in enumerate(ans):
self.cnt[i] -= v
for i, x in enumerate(ans):
self.cnt[i] -= x
return ans


Expand All @@ -126,8 +127,9 @@ class ATM:

```java
class ATM {
private long[] cnt = new long[5];
private int[] d = {20, 50, 100, 200, 500};
private int m = d.length;
private long[] cnt = new long[5];

public ATM() {
}
Expand All @@ -139,15 +141,15 @@ class ATM {
}

public int[] withdraw(int amount) {
int[] ans = new int[5];
for (int i = 4; i >= 0; --i) {
int[] ans = new int[m];
for (int i = m - 1; i >= 0; --i) {
ans[i] = (int) Math.min(amount / d[i], cnt[i]);
amount -= ans[i] * d[i];
}
if (amount > 0) {
return new int[] {-1};
}
for (int i = 0; i < 5; ++i) {
for (int i = 0; i < m; ++i) {
cnt[i] -= ans[i];
}
return ans;
Expand Down Expand Up @@ -177,23 +179,24 @@ public:
}

vector<int> withdraw(int amount) {
vector<int> ans(5);
for (int i = 4; ~i; --i) {
vector<int> ans(m);
for (int i = m - 1; ~i; --i) {
ans[i] = min(1ll * amount / d[i], cnt[i]);
amount -= ans[i] * d[i];
}
if (amount > 0) {
return {-1};
}
for (int i = 0; i < 5; ++i) {
for (int i = 0; i < m; ++i) {
cnt[i] -= ans[i];
}
return ans;
}

private:
long long cnt[5] = {0};
int d[5] = {20, 50, 100, 200, 500};
static constexpr int d[5] = {20, 50, 100, 200, 500};
static constexpr int m = size(d);
long long cnt[m] = {0};
};

/**
Expand All @@ -207,32 +210,33 @@ private:
#### Go
```go
type ATM struct {
d [5]int
cnt [5]int
}
var d = [...]int{20, 50, 100, 200, 500}
const m = len(d)
type ATM [m]int
func Constructor() ATM {
return ATM{[5]int{20, 50, 100, 200, 500}, [5]int{}}
return ATM{}
}
func (this *ATM) Deposit(banknotesCount []int) {
for i, v := range banknotesCount {
this.cnt[i] += v
for i, x := range banknotesCount {
this[i] += x
}
}
func (this *ATM) Withdraw(amount int) []int {
ans := make([]int, 5)
for i := 4; i >= 0; i-- {
ans[i] = min(amount/this.d[i], this.cnt[i])
amount -= ans[i] * this.d[i]
ans := make([]int, m)
for i := m - 1; i >= 0; i-- {
ans[i] = min(amount/d[i], this[i])
amount -= ans[i] * d[i]
}
if amount > 0 {
return []int{-1}
}
for i, v := range ans {
this.cnt[i] -= v
for i, x := range ans {
this[i] -= x
}
return ans
}
Expand All @@ -248,31 +252,32 @@ func (this *ATM) Withdraw(amount int) []int {
#### TypeScript

```ts
const d: number[] = [20, 50, 100, 200, 500];
const m = d.length;

class ATM {
private cnt: number[];
private d: number[];

constructor() {
this.cnt = [0, 0, 0, 0, 0];
this.d = [20, 50, 100, 200, 500];
this.cnt = Array(m).fill(0);
}

deposit(banknotesCount: number[]): void {
for (let i = 0; i < banknotesCount.length; i++) {
for (let i = 0; i < banknotesCount.length; ++i) {
this.cnt[i] += banknotesCount[i];
}
}

withdraw(amount: number): number[] {
let ans = [0, 0, 0, 0, 0];
for (let i = 4; i >= 0; i--) {
ans[i] = Math.min(Math.floor(amount / this.d[i]), this.cnt[i]);
amount -= ans[i] * this.d[i];
const ans: number[] = Array(m).fill(0);
for (let i = m - 1; i >= 0; --i) {
ans[i] = Math.min(Math.floor(amount / d[i]), this.cnt[i]);
amount -= ans[i] * d[i];
}
if (amount > 0) {
return [-1];
}
for (let i = 0; i < ans.length; i++) {
for (let i = 0; i < m; ++i) {
this.cnt[i] -= ans[i];
}
return ans;
Expand Down
Loading

0 comments on commit fd7c89f

Please sign in to comment.