Skip to content

Commit

Permalink
feat: add solutions to lc problem: No.2697 (#2084)
Browse files Browse the repository at this point in the history
No.2697.Lexicographically Smallest Palindrome
  • Loading branch information
yanglbme authored Dec 11, 2023
1 parent a242d2f commit 12cf12a
Show file tree
Hide file tree
Showing 9 changed files with 77 additions and 131 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@

**方法一:贪心 + 双指针**

我们用两个指针 $i$ 和 $j$ 分别指向字符串的首尾,初始时 $i=0,j=n-1$,其中 $n$ 是字符串的长度。每次比较 $s[i]$ 和 $s[j]$,如果二者不相同,则将其中较大的字符修改为较小的字符,使得两者相同。这样在修改之后,原字符串 $s$ 就变成了一个回文串
我们用两个指针 $i$ 和 $j$ 分别指向字符串的首尾,初始时 $i = 0$, $j = n - 1$。每一次,我们将 $s[i]$ 和 $s[j]$ 都修改为其中较小的那个字符,使得它们相等。修改之后,原字符串 $s$ 变成了一个回文串

时间复杂度 $O(n)$,其中 $n$ 是字符串的长度。我们只需要遍历一遍字符串即可。忽略答案的空间消耗,空间复杂度 $O(1)$。

Expand All @@ -67,11 +67,10 @@
```python
class Solution:
def makeSmallestPalindrome(self, s: str) -> str:
i, j = 0, len(s) - 1
cs = list(s)
i, j = 0, len(s) - 1
while i < j:
if s[i] != s[j]:
cs[i] = cs[j] = min(s[i], s[j])
cs[i] = cs[j] = min(cs[i], cs[j])
i, j = i + 1, j - 1
return "".join(cs)
```
Expand All @@ -85,11 +84,9 @@ class Solution {
public String makeSmallestPalindrome(String s) {
char[] cs = s.toCharArray();
for (int i = 0, j = cs.length - 1; i < j; ++i, --j) {
if (cs[i] != cs[j]) {
cs[i] = cs[j] = cs[i] < cs[j] ? cs[i] : cs[j];
}
cs[i] = cs[j] = (char) Math.min(cs[i], cs[j]);
}
return String.valueOf(cs);
return new String(cs);
}
}
```
Expand All @@ -101,9 +98,7 @@ class Solution {
public:
string makeSmallestPalindrome(string s) {
for (int i = 0, j = s.size() - 1; i < j; ++i, --j) {
if (s[i] != s[j]) {
s[i] = s[j] = s[i] < s[j] ? s[i] : s[j];
}
s[i] = s[j] = min(s[i], s[j]);
}
return s;
}
Expand All @@ -116,13 +111,8 @@ public:
func makeSmallestPalindrome(s string) string {
cs := []byte(s)
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
if cs[i] != cs[j] {
if cs[i] < cs[j] {
cs[j] = cs[i]
} else {
cs[i] = cs[j]
}
}
cs[i] = min(cs[i], cs[j])
cs[j] = cs[i]
}
return string(cs)
}
Expand All @@ -134,9 +124,7 @@ func makeSmallestPalindrome(s string) string {
function makeSmallestPalindrome(s: string): string {
const cs = s.split('');
for (let i = 0, j = s.length - 1; i < j; ++i, --j) {
if (s[i] !== s[j]) {
cs[i] = cs[j] = s[i] < s[j] ? s[i] : s[j];
}
cs[i] = cs[j] = String.fromCharCode(Math.min(cs[i].charCodeAt(0), cs[j].charCodeAt(0)));
}
return cs.join('');
}
Expand All @@ -147,24 +135,14 @@ function makeSmallestPalindrome(s: string): string {
```rust
impl Solution {
pub fn make_smallest_palindrome(s: String) -> String {
let mut b: Vec<u8> = s.bytes().collect();
let mut i = 0;
let mut j = b.len() - 1;

while i < j {
if b[i] != b[j] {
if b[i] < b[j] {
b[j] = b[i];
} else {
b[i] = b[j];
}
}

i += 1;
j -= 1;
let mut cs: Vec<char> = s.chars().collect();
let n = cs.len();
for i in 0..n / 2 {
let j = n - 1 - i;
cs[i] = std::cmp::min(cs[i], cs[j]);
cs[j] = cs[i];
}

String::from_utf8(b).unwrap()
cs.into_iter().collect()
}
}
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,23 @@

## Solutions

**Solution 1: Greedy + Two Pointers**

We use two pointers $i$ and $j$ to point to the beginning and end of the string, initially $i=0,j=n-1$, where $n$ is the length of the string. Each time we compare $s[i]$ and $s[j]$, if they are not the same, we modify the larger character to the smaller one to make them the same. After the modification, the original string $s$ becomes a palindrome.

The time complexity is $O(n)$, where $n$ is the length of the string. We only need to traverse the string once. Ignoring the space consumption of the answer, the space complexity is $O(1)$.

<!-- tabs:start -->

### **Python3**

```python
class Solution:
def makeSmallestPalindrome(self, s: str) -> str:
i, j = 0, len(s) - 1
cs = list(s)
i, j = 0, len(s) - 1
while i < j:
if s[i] != s[j]:
cs[i] = cs[j] = min(s[i], s[j])
cs[i] = cs[j] = min(cs[i], cs[j])
i, j = i + 1, j - 1
return "".join(cs)
```
Expand All @@ -70,11 +75,9 @@ class Solution {
public String makeSmallestPalindrome(String s) {
char[] cs = s.toCharArray();
for (int i = 0, j = cs.length - 1; i < j; ++i, --j) {
if (cs[i] != cs[j]) {
cs[i] = cs[j] = cs[i] < cs[j] ? cs[i] : cs[j];
}
cs[i] = cs[j] = (char) Math.min(cs[i], cs[j]);
}
return String.valueOf(cs);
return new String(cs);
}
}
```
Expand All @@ -86,9 +89,7 @@ class Solution {
public:
string makeSmallestPalindrome(string s) {
for (int i = 0, j = s.size() - 1; i < j; ++i, --j) {
if (s[i] != s[j]) {
s[i] = s[j] = s[i] < s[j] ? s[i] : s[j];
}
s[i] = s[j] = min(s[i], s[j]);
}
return s;
}
Expand All @@ -101,13 +102,8 @@ public:
func makeSmallestPalindrome(s string) string {
cs := []byte(s)
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
if cs[i] != cs[j] {
if cs[i] < cs[j] {
cs[j] = cs[i]
} else {
cs[i] = cs[j]
}
}
cs[i] = min(cs[i], cs[j])
cs[j] = cs[i]
}
return string(cs)
}
Expand All @@ -119,9 +115,7 @@ func makeSmallestPalindrome(s string) string {
function makeSmallestPalindrome(s: string): string {
const cs = s.split('');
for (let i = 0, j = s.length - 1; i < j; ++i, --j) {
if (s[i] !== s[j]) {
cs[i] = cs[j] = s[i] < s[j] ? s[i] : s[j];
}
cs[i] = cs[j] = String.fromCharCode(Math.min(cs[i].charCodeAt(0), cs[j].charCodeAt(0)));
}
return cs.join('');
}
Expand All @@ -132,24 +126,14 @@ function makeSmallestPalindrome(s: string): string {
```rust
impl Solution {
pub fn make_smallest_palindrome(s: String) -> String {
let mut b: Vec<u8> = s.bytes().collect();
let mut i = 0;
let mut j = b.len() - 1;

while i < j {
if b[i] != b[j] {
if b[i] < b[j] {
b[j] = b[i];
} else {
b[i] = b[j];
}
}

i += 1;
j -= 1;
let mut cs: Vec<char> = s.chars().collect();
let n = cs.len();
for i in 0..n / 2 {
let j = n - 1 - i;
cs[i] = std::cmp::min(cs[i], cs[j]);
cs[j] = cs[i];
}

String::from_utf8(b).unwrap()
cs.into_iter().collect()
}
}
```
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
class Solution {
public:
string makeSmallestPalindrome(string s) {
for (int i = 0, j = s.size() - 1; i < j; ++i, --j) {
if (s[i] != s[j]) {
s[i] = s[j] = s[i] < s[j] ? s[i] : s[j];
}
}
return s;
}
class Solution {
public:
string makeSmallestPalindrome(string s) {
for (int i = 0, j = s.size() - 1; i < j; ++i, --j) {
s[i] = s[j] = min(s[i], s[j]);
}
return s;
}
};
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
func makeSmallestPalindrome(s string) string {
cs := []byte(s)
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
if cs[i] != cs[j] {
if cs[i] < cs[j] {
cs[j] = cs[i]
} else {
cs[i] = cs[j]
}
}
cs[i] = min(cs[i], cs[j])
cs[j] = cs[i]
}
return string(cs)
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
class Solution {
public String makeSmallestPalindrome(String s) {
char[] cs = s.toCharArray();
for (int i = 0, j = cs.length - 1; i < j; ++i, --j) {
if (cs[i] != cs[j]) {
cs[i] = cs[j] = cs[i] < cs[j] ? cs[i] : cs[j];
}
}
return String.valueOf(cs);
}
class Solution {
public String makeSmallestPalindrome(String s) {
char[] cs = s.toCharArray();
for (int i = 0, j = cs.length - 1; i < j; ++i, --j) {
cs[i] = cs[j] = (char) Math.min(cs[i], cs[j]);
}
return new String(cs);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
class Solution:
def makeSmallestPalindrome(self, s: str) -> str:
i, j = 0, len(s) - 1
cs = list(s)
while i < j:
if s[i] != s[j]:
cs[i] = cs[j] = min(s[i], s[j])
i, j = i + 1, j - 1
return "".join(cs)
class Solution:
def makeSmallestPalindrome(self, s: str) -> str:
cs = list(s)
i, j = 0, len(s) - 1
while i < j:
cs[i] = cs[j] = min(cs[i], cs[j])
i, j = i + 1, j - 1
return "".join(cs)
Original file line number Diff line number Diff line change
@@ -1,22 +1,12 @@
impl Solution {
pub fn make_smallest_palindrome(s: String) -> String {
let mut b: Vec<u8> = s.bytes().collect();
let mut i = 0;
let mut j = b.len() - 1;

while i < j {
if b[i] != b[j] {
if b[i] < b[j] {
b[j] = b[i];
} else {
b[i] = b[j];
}
}

i += 1;
j -= 1;
let mut cs: Vec<char> = s.chars().collect();
let n = cs.len();
for i in 0..n / 2 {
let j = n - 1 - i;
cs[i] = std::cmp::min(cs[i], cs[j]);
cs[j] = cs[i];
}

String::from_utf8(b).unwrap()
cs.into_iter().collect()
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
function makeSmallestPalindrome(s: string): string {
const cs = s.split('');
for (let i = 0, j = s.length - 1; i < j; ++i, --j) {
if (s[i] !== s[j]) {
cs[i] = cs[j] = s[i] < s[j] ? s[i] : s[j];
}
cs[i] = cs[j] = String.fromCharCode(Math.min(cs[i].charCodeAt(0), cs[j].charCodeAt(0)));
}
return cs.join('');
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ Now, all the numbers in nums are non-positive. Therefore, we return 3.

## Solutions

**Solution 1: Binary Search**

We notice that if an operation count $t$ can make all numbers less than or equal to $0$, then for any $t' > t$, the operation count $t'$ can also make all numbers less than or equal to $0$. Therefore, we can use binary search to find the minimum operation count.

We define the left boundary of the binary search as $l=0$, and the right boundary as $r=\max(nums)$. Each time we perform a binary search, we find the middle value $mid=\lfloor\frac{l+r}{2}\rfloor$, and then determine whether there exists an operation method that does not exceed $mid$ and makes all numbers less than or equal to $0$. If it exists, we update the right boundary $r = mid$, otherwise, we update the left boundary

<!-- tabs:start -->

### **Python3**
Expand Down

0 comments on commit 12cf12a

Please sign in to comment.