一、反转字符串中的元音字符
力扣
解题思路:
使用双指针,一个指针从头向尾遍历,一个指针从尾到头遍历,当两个指针都遍历到元音字符时,交换这两个元音字符。
代码:
private final static HashSet<Character> vowels = new HashSet<>(
Arrays.asList('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'));
public String reverseVowels(String s) {
if (s == null) return null;
int i = 0, j = s.length() - 1;
char[] result = new char[s.length()];
while (i <= j) {
char ci = s.charAt(i);
char cj = s.charAt(j);
if (!vowels.contains(ci)) {
result[i++] = ci;
} else if (!vowels.contains(cj)) {
result[j--] = cj;
} else {
result[i++] = cj;
result[j--] = ci;
}
}
return new String(result);
}
二、快速排序
代码:
public class sort {
public void quickSort(int[] arr, int low, int high) {
if (low < high) {
int index = getIndex(arr, low, high);
//以排好序的元素为界,将原数组分为两部分,递归
quickSort(arr, 0, index - 1);
quickSort(arr, index + 1, high);
}
}
public int getIndex(int[] arr, int low, int high) {
int tmp=arr[low];
int i=low;
int j=high;
int t;
while (true) {
// 当队尾的元素大于等于基准数据时,向前挪动high指针
while(arr[j] >= tmp && i < j)
j--;
while(arr[i] <= tmp && i < j)//再找右边的
i++;
if(i < j)//交换两个数在数组中的位置
{
t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
else
break;
}
arr[low] = arr[i];
arr[i] = tmp;
return i;
}
public static void main (String[]args)
{
int a[]={4,5,7,1,3,2,6};
sort test=new sort();
test.quickSort(a,0,6);
for(int i=0;i<=6;i++)
{
System.out.println(a[i]);
}
}
}
三、归并排序
代码:
public class MergeSort {
public static void sort(int[] nums, int low, int high) {
int mid = (low + high) / 2;
if (low < high) {
// 左边
sort(nums, low, mid);
// 右边
sort(nums, mid + 1, high);
// 左右归并
merge(nums, low, mid, high);
}
}
public static void merge(int[] nums, int low, int mid, int high) {
int[] temp = new int[high - low + 1];
int i = low;// 左指针
int j = mid + 1;// 右指针
int k = 0;
// 把较小的数先移到新数组中
while (i <= mid && j <= high) {
if (nums[i] < nums[j]) {
temp[k++] = nums[i++];
} else {
temp[k++] = nums[j++];
}
}
// 把左边剩余的数移入数组
while (i <= mid) {
temp[k++] = nums[i++];
}
// 把右边边剩余的数移入数组
while (j <= high) {
temp[k++] = nums[j++];
}
// 把新数组中的数覆盖nums数组
for (int k2 = 0; k2 < temp.length; k2++) {
nums[k2 + low] = temp[k2];
}
}
public static void main(String[]args)
{
int arr[]={1,2,7,4,6,5,3};
MergeSort mergeSort=new MergeSort();
mergeSort.sort(arr, 0, 6);
for(int i=0;i<=6;i++)
{
System.out.println(arr[i]);
}
}
}
四、最长子序列
解题思路:
直接在未排序的字典 dd 中查找字符串 xx 满足 xx 是 ss 的子序列。如果 xx 被找到了,我们将它与其他匹配的字符串做比较,直到找到长度最长、字典序最小的单词为止。
代码:
public class Solution {
public boolean isSubsequence(String x, String y) {
int j = 0;
for (int i = 0; i < y.length() && j < x.length(); i++)
if (x.charAt(j) == y.charAt(i))
j++;
return j == x.length();
}
public String findLongestWord(String s, List < String > d) {
String max_str = "";
for (String str: d) {
if (isSubsequence(str, s)) {
if (str.length() > max_str.length() || (str.length() == max_str.length() && str.compareTo(max_str) < 0))
max_str = str;
}
}
return max_str;
}
}
五、回文字符串
解题思路:
本题的关键是处理删除一个字符。在使用双指针遍历字符串时,如果出现两个指针指向的字符不相等的情况,我们就试着删除一个字符,再判断删除完之后的字符串是否是回文字符串。
在判断是否为回文字符串时,我们不需要判断整个字符串,因为左指针左边和右指针右边的字符之前已经判断过具有对称性质,所以只需要判断中间的子字符串即可。
在试着删除字符时,我们既可以删除左指针指向的字符,也可以删除右指针指向的字符。
代码:
public boolean validPalindrome(String s) {
for (int i = 0, j = s.length() - 1; i < j; i++, j--) {
if (s.charAt(i) != s.charAt(j)) {
return isPalindrome(s, i, j - 1) || isPalindrome(s, i + 1, j);
}
}
return true;
}
private boolean isPalindrome(String s, int i, int j) {
while (i < j) {
if (s.charAt(i++) != s.charAt(j--)) {
return false;
}
}
return true;
}