package com.gientech.iomp;
class Solution {
public String longestPalindrome(String s) {
if (s == null || s.length() < 2) {
return s == null ? "" : s;
}
int start = 0;
int end = 0;
for (int i = 0; i < s.length(); i++) {
// 奇数长度
int len1 = expandAroundCenter(s, i, i);
// 偶数长度
int len2 = expandAroundCenter(s, i, i + 1);
int len = Math.max(len1, len2);
if (len > end - start + 1) {
start = i - (len - 1) / 2;
end = i + len / 2;
}
}
return s.substring(start, end + 1);
}
private int expandAroundCenter(String s, int left, int right) {
int l = left;
int r = right;
// 扩展,直到不能扩展为止
while (l >= 0 && r < s.length() && s.charAt(l) == s.charAt(r)) {
l--;
r++;
}
// 扩展结束后真实长度
return r - l - 1;
}
}
解题思路:使用中心扩展法
中心扩展法
-
回文串的本质:从中间向两边对称
-
回文中心分两种:
- 奇数长度:
aba→ 中心是一个字符 - 偶数长度:
abba→ 中心是两个字符之间
- 奇数长度:
所以:
-
枚举每一个位置
i -
尝试:
i, i(奇数回文)i, i+1(偶数回文)
-
以该中心不断向左右扩展,得到以该中心为基准的最长回文长度
-
取所有中心中的最大值
class Solution {
public void merge(int\[] nums1, int m, int\[] nums2, int n) {
// 初始化指针 i, j 分别指向 nums1 和 nums2 的有效部分末尾
// k 指向 nums1 的末尾(预留空间的最后一格)
int i = m - 1;
int j = n - 1;
int k = m + n - 1;
// 从后往前合并,比较 nums1 和 nums2 当前末尾的元素
while (i >= 0 && j >= 0) {
if (nums1[i] > nums2[j]) {
// nums1 当前元素较大,放入末尾
nums1[k--] = nums1[i--];
} else {
// nums2 当前元素较大,放入末尾
nums1[k--] = nums2[j--];
}
}
// 如果 nums2 还有剩余元素,拷贝到 nums1 的前面空位
while (j >= 0) {
nums1[k--] = nums2[j--];
}
// 不需要处理 nums1 剩余部分,因为它们已经在正确位置上
}
}```
解题思路:
nums1 后面有足够空间\
从数组末尾开始比较\
每次把较大的数放到 nums1 的最后\
指针向前移动,直到合并完成