Skip to content

Commit c0e6aef

Browse files
authored
feat: add solutions to lc problems: No.3766,3767 (#4884)
1 parent 8327ccd commit c0e6aef

File tree

14 files changed

+918
-16
lines changed

14 files changed

+918
-16
lines changed

solution/3700-3799/3766.Minimum Operations to Make Binary Palindrome/README.md

Lines changed: 174 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -155,32 +155,202 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3700-3799/3766.Mi
155155

156156
<!-- solution:start -->
157157

158-
### 方法一
158+
### 方法一:预处理 + 二分查找
159+
160+
我们注意到,题目中给定的数字范围仅为 $[1, 5000]$,因此,我们直接预处理 $[0, 2^{14})$ 范围内的所有二进制回文数,并将其存储在一个数组中,记为 $\textit{primes}$。
161+
162+
接下来,对于每个数字 $x$,我们使用二分查找在数组 $\textit{primes}$ 中找到第一个大于等于 $x$ 的回文数 $\textit{primes}[i]$,以及第一个小于 $x$ 的回文数 $\textit{primes}[i - 1]$。然后,我们计算将 $x$ 转换为这两个回文数所需的操作次数,并取其中的最小值作为答案。
163+
164+
时间复杂度 $O(n \times \log M)$,空间复杂度 $O(M)$。其中 $n$ 是数组 $\textit{nums}$ 的长度,而 $M$ 是预处理的二进制回文数的数量。
159165

160166
<!-- tabs:start -->
161167

162168
#### Python3
163169

164170
```python
165-
171+
primes = []
172+
for i in range(1 << 14):
173+
s = bin(i)[2:]
174+
if s == s[::-1]:
175+
primes.append(i)
176+
177+
178+
class Solution:
179+
def minOperations(self, nums: List[int]) -> List[int]:
180+
ans = []
181+
for x in nums:
182+
i = bisect_left(primes, x)
183+
times = inf
184+
if i < len(primes):
185+
times = min(times, primes[i] - x)
186+
if i >= 1:
187+
times = min(times, x - primes[i - 1])
188+
ans.append(times)
189+
return ans
166190
```
167191

168192
#### Java
169193

170194
```java
171-
195+
class Solution {
196+
private static final List<Integer> primes = new ArrayList<>();
197+
198+
static {
199+
int N = 1 << 14;
200+
for (int i = 0; i < N; i++) {
201+
String s = Integer.toBinaryString(i);
202+
String rs = new StringBuilder(s).reverse().toString();
203+
if (s.equals(rs)) {
204+
primes.add(i);
205+
}
206+
}
207+
}
208+
209+
public int[] minOperations(int[] nums) {
210+
int n = nums.length;
211+
int[] ans = new int[n];
212+
Arrays.fill(ans, Integer.MAX_VALUE);
213+
for (int k = 0; k < n; ++k) {
214+
int x = nums[k];
215+
int i = binarySearch(primes, x);
216+
if (i < primes.size()) {
217+
ans[k] = Math.min(ans[k], primes.get(i) - x);
218+
}
219+
if (i >= 1) {
220+
ans[k] = Math.min(ans[k], x - primes.get(i - 1));
221+
}
222+
}
223+
224+
return ans;
225+
}
226+
227+
private int binarySearch(List<Integer> primes, int x) {
228+
int l = 0, r = primes.size();
229+
while (l < r) {
230+
int mid = (l + r) >>> 1;
231+
if (primes.get(mid) >= x) {
232+
r = mid;
233+
} else {
234+
l = mid + 1;
235+
}
236+
}
237+
return l;
238+
}
239+
}
172240
```
173241

174242
#### C++
175243

176244
```cpp
177-
245+
vector<int> primes;
246+
247+
auto init = [] {
248+
int N = 1 << 14;
249+
for (int i = 0; i < N; ++i) {
250+
string s = bitset<14>(i).to_string();
251+
s = s.substr(s.find_first_not_of('0') == string::npos ? 13 : s.find_first_not_of('0'));
252+
string rs = s;
253+
reverse(rs.begin(), rs.end());
254+
if (s == rs) {
255+
primes.push_back(i);
256+
}
257+
}
258+
return 0;
259+
}();
260+
261+
class Solution {
262+
public:
263+
vector<int> minOperations(vector<int>& nums) {
264+
int n = nums.size();
265+
vector<int> ans(n, INT_MAX);
266+
for (int k = 0; k < n; ++k) {
267+
int x = nums[k];
268+
int i = lower_bound(primes.begin(), primes.end(), x) - primes.begin();
269+
if (i < (int) primes.size()) {
270+
ans[k] = min(ans[k], primes[i] - x);
271+
}
272+
if (i >= 1) {
273+
ans[k] = min(ans[k], x - primes[i - 1]);
274+
}
275+
}
276+
return ans;
277+
}
278+
};
178279
```
179280
180281
#### Go
181282
182283
```go
284+
var primes []int
285+
286+
func init() {
287+
N := 1 << 14
288+
for i := 0; i < N; i++ {
289+
s := strconv.FormatInt(int64(i), 2)
290+
if isPalindrome(s) {
291+
primes = append(primes, i)
292+
}
293+
}
294+
}
295+
296+
func isPalindrome(s string) bool {
297+
runes := []rune(s)
298+
for i := 0; i < len(runes)/2; i++ {
299+
if runes[i] != runes[len(runes)-1-i] {
300+
return false
301+
}
302+
}
303+
return true
304+
}
305+
306+
func minOperations(nums []int) []int {
307+
ans := make([]int, len(nums))
308+
for k, x := range nums {
309+
i := sort.SearchInts(primes, x)
310+
t := math.MaxInt32
311+
if i < len(primes) {
312+
t = primes[i] - x
313+
}
314+
if i >= 1 {
315+
t = min(t, x-primes[i-1])
316+
}
317+
ans[k] = t
318+
}
319+
return ans
320+
}
321+
```
183322

323+
#### TypeScript
324+
325+
```ts
326+
const primes: number[] = (() => {
327+
const res: number[] = [];
328+
const N = 1 << 14;
329+
for (let i = 0; i < N; i++) {
330+
const s = i.toString(2);
331+
if (s === s.split('').reverse().join('')) {
332+
res.push(i);
333+
}
334+
}
335+
return res;
336+
})();
337+
338+
function minOperations(nums: number[]): number[] {
339+
const ans: number[] = Array(nums.length).fill(Number.MAX_SAFE_INTEGER);
340+
341+
for (let k = 0; k < nums.length; k++) {
342+
const x = nums[k];
343+
const i = _.sortedIndex(primes, x);
344+
if (i < primes.length) {
345+
ans[k] = primes[i] - x;
346+
}
347+
if (i >= 1) {
348+
ans[k] = Math.min(ans[k], x - primes[i - 1]);
349+
}
350+
}
351+
352+
return ans;
353+
}
184354
```
185355

186356
<!-- tabs:end -->

0 commit comments

Comments
 (0)