参考了很多大佬的题解,仅作为自己学习笔记用。
57-1. 和为s的两个数字
题意:
输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。
题解:
利用双指针,一头一尾相互靠近求和,对撞指针。
public int[] twoSum(int[] nums, int target) {
int i =0, j = nums.length-1;
while(i < j){
int sum = nums[i] + nums[j];
if(sum == target){
return new int[] {nums[i], nums[j]};
}else if(sum > target){
j--;
}else{
i++;
}
}
return new int[0];
}
57-2. 和为s的连续正数序列
题意:
输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。
序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。
题解:
i 从 1 开始,j 从 2 开始,当 sum 大了的时候,i 右移,当 sum 小了的时候, j 右移。
public int[][] findContinuousSequence(int target) {
ArrayList<int[]> res = new ArrayList<>();
int i = 1, j = 2;
while(i < j){
int sum = (i + j) * (j - i + 1) / 2;
if(sum == target){
int[] tep = new int[j - i + 1];
for(int k = i; k <= j; k++){
tep[k - i] = k;
}
res.add(tep);
i++;
}else if(sum < target){
j++;
}else{
i++;
}
}
return res.toArray(new int[res.size()][]);
}
58-1. 翻转单词顺序
题意:
输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student. “,则输出"student. a am I”。
题解1:
双指针,删除首尾空格,然后从后往前搜索空格,遇到空格就截取 i 和 j 之间的单词,然后指针继续走,截取下一个。
public String reverseWords(String s) {
s = s.trim();
int j = s.length() - 1, i = j;
StringBuilder sb = new StringBuilder();
while(i >= 0){
while(i >=0 && s.charAt(i) != ' ') i--;
sb.append(s.substring(i + 1, j + 1) + " ");
while(i >=0 && s.charAt(i) == ' ') i--;
j = i;
}
return sb.toString().trim();
}
题解2:
分割 + 倒序。
public String reverseWords(String s) {
String[] arr = s.split(" "); //按空格进行切割
StringBuilder sb = new StringBuilder();
for (int i = arr.length - 1; i >= 0; i--) {
if (!arr[i].equals("")) { //判断如果不是""就添加进去,并且加个空格
sb.append(arr[i]).append(" ");
}
}
return sb.toString().trim(); //删除前后所有的空格
}
58-2. 左旋转字符串
题意:
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。
题解1:
字符串切片。一行代码。
public String reverseLeftWords(String s, int n) {
return s.substring(n) + s.substring(0, n);
}
题解2:
如果不允许切片,可以遍历拼接。
public String reverseLeftWords(String s, int n) {
StringBuilder res = new StringBuilder();
for(int i = n; i < s.length(); i++)
res.append(s.charAt(i));
for(int i = 0; i < n; i++)
res.append(s.charAt(i));
return res.toString();
}
题解3:
局部反转 + 整体反转。
class Solution {
public String reverseLeftWords(String s, int n) {
if(n > s.length()) return s;
char[] arr = s.toCharArray();
reverse(arr, 0, n - 1); //反转前半部分
reverse(arr, n, arr.length - 1); //反转后半部分
reverse(arr, 0, arr.length - 1); //整体反转
return new String(arr);
}
void reverse(char[] arr, int i, int j){
while(i < j){
swap(arr, i, j);
i++;
j--;
}
}
void swap(char[] arr, int i, int j){
char t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
}