Skip to content

Commit 7023118

Browse files
authored
feat: add solutions to lc problem: No.0728 (#3567)
No.0728.Self Dividing Numbers
1 parent 2913062 commit 7023118

File tree

8 files changed

+199
-149
lines changed

8 files changed

+199
-149
lines changed

solution/0700-0799/0728.Self Dividing Numbers/README.md

+70-49
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,15 @@ tags:
5656

5757
<!-- solution:start -->
5858

59-
### 方法一
59+
### 方法一:模拟
60+
61+
我们定义一个函数 $\textit{check}(x)$,用来判断 $x$ 是否是自除数。函数的实现思路如下:
62+
63+
我们用 $y$ 来记录 $x$ 的值,然后不断地对 $y$ 除以 $10$,直到 $y$ 为 $0$。在这个过程中,我们判断 $y$ 的末位是否为 $0$,或者 $x$ 是否不能被 $y$ 的末位整除,如果满足这两个条件中的任意一个,那么 $x$ 就不是自除数,返回 $\text{false}$。否则遍历完所有的位数后,返回 $\text{true}$。
64+
65+
最后,我们遍历区间 $[\textit{left}, \textit{right}]$ 中的所有数,对每个数调用 $\textit{check}(x)$,如果返回 $\text{true}$,那么我们就将这个数加入答案数组中。
66+
67+
时间复杂度 $O(n \times \log_{10} M)$,其中 $n$ 是区间 $[\textit{left}, \textit{right}]$ 中的元素个数,而 $M = \textit{right}$,表示区间中的最大值。
6068

6169
<!-- tabs:start -->
6270

@@ -65,11 +73,15 @@ tags:
6573
```python
6674
class Solution:
6775
def selfDividingNumbers(self, left: int, right: int) -> List[int]:
68-
return [
69-
num
70-
for num in range(left, right + 1)
71-
if all(i != '0' and num % int(i) == 0 for i in str(num))
72-
]
76+
def check(x: int) -> bool:
77+
y = x
78+
while y:
79+
if y % 10 == 0 or x % (y % 10):
80+
return False
81+
y //= 10
82+
return True
83+
84+
return [x for x in range(left, right + 1) if check(x)]
7385
```
7486

7587
#### Java
@@ -78,18 +90,17 @@ class Solution:
7890
class Solution {
7991
public List<Integer> selfDividingNumbers(int left, int right) {
8092
List<Integer> ans = new ArrayList<>();
81-
for (int i = left; i <= right; ++i) {
82-
if (check(i)) {
83-
ans.add(i);
93+
for (int x = left; x <= right; ++x) {
94+
if (check(x)) {
95+
ans.add(x);
8496
}
8597
}
8698
return ans;
8799
}
88100

89-
private boolean check(int num) {
90-
for (int t = num; t != 0; t /= 10) {
91-
int x = t % 10;
92-
if (x == 0 || num % x != 0) {
101+
private boolean check(int x) {
102+
for (int y = x; y > 0; y /= 10) {
103+
if (y % 10 == 0 || x % (y % 10) != 0) {
93104
return false;
94105
}
95106
}
@@ -104,44 +115,59 @@ class Solution {
104115
class Solution {
105116
public:
106117
vector<int> selfDividingNumbers(int left, int right) {
118+
auto check = [&](int x) -> bool {
119+
for (int y = x; y; y /= 10) {
120+
if (y % 10 == 0 || x % (y % 10)) {
121+
return false;
122+
}
123+
}
124+
return true;
125+
};
107126
vector<int> ans;
108-
for (int i = left; i <= right; ++i)
109-
if (check(i))
110-
ans.push_back(i);
111-
return ans;
112-
}
113-
114-
bool check(int num) {
115-
for (int t = num; t; t /= 10) {
116-
int x = t % 10;
117-
if (x == 0 || num % x) return false;
127+
for (int x = left; x <= right; ++x) {
128+
if (check(x)) {
129+
ans.push_back(x);
130+
}
118131
}
119-
return true;
132+
return ans;
120133
}
121134
};
122135
```
123136
124137
#### Go
125138
126139
```go
127-
func selfDividingNumbers(left int, right int) []int {
128-
check := func(num int) bool {
129-
for t := num; t != 0; t /= 10 {
130-
x := t % 10
131-
if x == 0 || num%x != 0 {
140+
func selfDividingNumbers(left int, right int) (ans []int) {
141+
check := func(x int) bool {
142+
for y := x; y > 0; y /= 10 {
143+
if y%10 == 0 || x%(y%10) != 0 {
132144
return false
133145
}
134146
}
135147
return true
136148
}
137-
138-
var ans []int
139-
for i := left; i <= right; i++ {
140-
if check(i) {
141-
ans = append(ans, i)
149+
for x := left; x <= right; x++ {
150+
if check(x) {
151+
ans = append(ans, x)
142152
}
143153
}
144-
return ans
154+
return
155+
}
156+
```
157+
158+
#### TypeScript
159+
160+
```ts
161+
function selfDividingNumbers(left: number, right: number): number[] {
162+
const check = (x: number): boolean => {
163+
for (let y = x; y; y = Math.floor(y / 10)) {
164+
if (y % 10 === 0 || x % (y % 10) !== 0) {
165+
return false;
166+
}
167+
}
168+
return true;
169+
};
170+
return Array.from({ length: right - left + 1 }, (_, i) => i + left).filter(check);
145171
}
146172
```
147173

@@ -150,23 +176,18 @@ func selfDividingNumbers(left int, right int) []int {
150176
```rust
151177
impl Solution {
152178
pub fn self_dividing_numbers(left: i32, right: i32) -> Vec<i32> {
153-
let mut res = vec![];
154-
for i in left..=right {
155-
let mut num = i;
156-
if (loop {
157-
if num == 0 {
158-
break true;
179+
fn check(x: i32) -> bool {
180+
let mut y = x;
181+
while y > 0 {
182+
if y % 10 == 0 || x % (y % 10) != 0 {
183+
return false;
159184
}
160-
let j = num % 10;
161-
if j == 0 || i % j != 0 {
162-
break false;
163-
}
164-
num /= 10;
165-
}) {
166-
res.push(i);
185+
y /= 10;
167186
}
187+
true
168188
}
169-
res
189+
190+
(left..=right).filter(|&x| check(x)).collect()
170191
}
171192
}
172193
```

solution/0700-0799/0728.Self Dividing Numbers/README_EN.md

+70-49
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,15 @@ tags:
4747

4848
<!-- solution:start -->
4949

50-
### Solution 1
50+
### Solution 1: Simulation
51+
52+
We define a function $\textit{check}(x)$ to determine whether $x$ is a self-dividing number. The implementation idea of the function is as follows:
53+
54+
We use $y$ to record the value of $x$, and then continuously divide $y$ by $10$ until $y$ is $0$. During this process, we check whether the last digit of $y$ is $0$, or whether $x$ cannot be divided by the last digit of $y$. If either of these conditions is met, then $x$ is not a self-dividing number, and we return $\text{false}$. Otherwise, after traversing all the digits, we return $\text{true}$.
55+
56+
Finally, we traverse all the numbers in the interval $[\textit{left}, \textit{right}]$, and for each number, we call $\textit{check}(x)$. If it returns $\text{true}$, we add this number to the answer array.
57+
58+
The time complexity is $O(n \times \log_{10} M)$, where $n$ is the number of elements in the interval $[\textit{left}, \textit{right}]$, and $M = \textit{right}$, which is the maximum value in the interval.
5159

5260
<!-- tabs:start -->
5361

@@ -56,11 +64,15 @@ tags:
5664
```python
5765
class Solution:
5866
def selfDividingNumbers(self, left: int, right: int) -> List[int]:
59-
return [
60-
num
61-
for num in range(left, right + 1)
62-
if all(i != '0' and num % int(i) == 0 for i in str(num))
63-
]
67+
def check(x: int) -> bool:
68+
y = x
69+
while y:
70+
if y % 10 == 0 or x % (y % 10):
71+
return False
72+
y //= 10
73+
return True
74+
75+
return [x for x in range(left, right + 1) if check(x)]
6476
```
6577

6678
#### Java
@@ -69,18 +81,17 @@ class Solution:
6981
class Solution {
7082
public List<Integer> selfDividingNumbers(int left, int right) {
7183
List<Integer> ans = new ArrayList<>();
72-
for (int i = left; i <= right; ++i) {
73-
if (check(i)) {
74-
ans.add(i);
84+
for (int x = left; x <= right; ++x) {
85+
if (check(x)) {
86+
ans.add(x);
7587
}
7688
}
7789
return ans;
7890
}
7991

80-
private boolean check(int num) {
81-
for (int t = num; t != 0; t /= 10) {
82-
int x = t % 10;
83-
if (x == 0 || num % x != 0) {
92+
private boolean check(int x) {
93+
for (int y = x; y > 0; y /= 10) {
94+
if (y % 10 == 0 || x % (y % 10) != 0) {
8495
return false;
8596
}
8697
}
@@ -95,44 +106,59 @@ class Solution {
95106
class Solution {
96107
public:
97108
vector<int> selfDividingNumbers(int left, int right) {
109+
auto check = [&](int x) -> bool {
110+
for (int y = x; y; y /= 10) {
111+
if (y % 10 == 0 || x % (y % 10)) {
112+
return false;
113+
}
114+
}
115+
return true;
116+
};
98117
vector<int> ans;
99-
for (int i = left; i <= right; ++i)
100-
if (check(i))
101-
ans.push_back(i);
102-
return ans;
103-
}
104-
105-
bool check(int num) {
106-
for (int t = num; t; t /= 10) {
107-
int x = t % 10;
108-
if (x == 0 || num % x) return false;
118+
for (int x = left; x <= right; ++x) {
119+
if (check(x)) {
120+
ans.push_back(x);
121+
}
109122
}
110-
return true;
123+
return ans;
111124
}
112125
};
113126
```
114127
115128
#### Go
116129
117130
```go
118-
func selfDividingNumbers(left int, right int) []int {
119-
check := func(num int) bool {
120-
for t := num; t != 0; t /= 10 {
121-
x := t % 10
122-
if x == 0 || num%x != 0 {
131+
func selfDividingNumbers(left int, right int) (ans []int) {
132+
check := func(x int) bool {
133+
for y := x; y > 0; y /= 10 {
134+
if y%10 == 0 || x%(y%10) != 0 {
123135
return false
124136
}
125137
}
126138
return true
127139
}
128-
129-
var ans []int
130-
for i := left; i <= right; i++ {
131-
if check(i) {
132-
ans = append(ans, i)
140+
for x := left; x <= right; x++ {
141+
if check(x) {
142+
ans = append(ans, x)
133143
}
134144
}
135-
return ans
145+
return
146+
}
147+
```
148+
149+
#### TypeScript
150+
151+
```ts
152+
function selfDividingNumbers(left: number, right: number): number[] {
153+
const check = (x: number): boolean => {
154+
for (let y = x; y; y = Math.floor(y / 10)) {
155+
if (y % 10 === 0 || x % (y % 10) !== 0) {
156+
return false;
157+
}
158+
}
159+
return true;
160+
};
161+
return Array.from({ length: right - left + 1 }, (_, i) => i + left).filter(check);
136162
}
137163
```
138164

@@ -141,23 +167,18 @@ func selfDividingNumbers(left int, right int) []int {
141167
```rust
142168
impl Solution {
143169
pub fn self_dividing_numbers(left: i32, right: i32) -> Vec<i32> {
144-
let mut res = vec![];
145-
for i in left..=right {
146-
let mut num = i;
147-
if (loop {
148-
if num == 0 {
149-
break true;
170+
fn check(x: i32) -> bool {
171+
let mut y = x;
172+
while y > 0 {
173+
if y % 10 == 0 || x % (y % 10) != 0 {
174+
return false;
150175
}
151-
let j = num % 10;
152-
if j == 0 || i % j != 0 {
153-
break false;
154-
}
155-
num /= 10;
156-
}) {
157-
res.push(i);
176+
y /= 10;
158177
}
178+
true
159179
}
160-
res
180+
181+
(left..=right).filter(|&x| check(x)).collect()
161182
}
162183
}
163184
```
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
class Solution {
22
public:
33
vector<int> selfDividingNumbers(int left, int right) {
4+
auto check = [&](int x) -> bool {
5+
for (int y = x; y; y /= 10) {
6+
if (y % 10 == 0 || x % (y % 10)) {
7+
return false;
8+
}
9+
}
10+
return true;
11+
};
412
vector<int> ans;
5-
for (int i = left; i <= right; ++i)
6-
if (check(i))
7-
ans.push_back(i);
8-
return ans;
9-
}
10-
11-
bool check(int num) {
12-
for (int t = num; t; t /= 10) {
13-
int x = t % 10;
14-
if (x == 0 || num % x) return false;
13+
for (int x = left; x <= right; ++x) {
14+
if (check(x)) {
15+
ans.push_back(x);
16+
}
1517
}
16-
return true;
18+
return ans;
1719
}
18-
};
20+
};

0 commit comments

Comments
 (0)