18. 四数之和
给你一个由 n
个整数组成的数组 nums
,和一个目标值 target
。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]]
(若两个四元组元素一一对应,则认为两个四元组重复):
0 <= a, b, c, d < n
a
、b
、c
和d
互不相同nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。
示例 1:
输入:nums = [1,0,-1,0,-2,2], target = 0 输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
//定义结果集
List<List<Integer>> result = new ArrayList<>();
//先排序数组
Arrays.sort(nums);
for(int i = 0; i < nums.length; i++){
//对nums[i]剪枝
if(nums[i]>0 && target>0 && nums[i]>target) break;
//对nums[i]去重
if(i>0 && nums[i-1]==nums[i]) continue;
for(int j = i+1; j < nums.length; j++){
//对nums[j]剪枝
if( nums[i] + nums[j]>target && target>0) break;
//对nums[j]去重
if(j>i+1 && nums[j-1]==nums[j]) continue;
//双指针法
int left = j + 1;
int right = nums.length - 1;
while(left < right){
//防止溢出异常
long total = (long) nums[i] + nums[j] + nums[left] + nums[right];
if(total < target){
left++;
} else if(total > target){
right--;
} else{
result.add(Arrays.asList(nums[i],nums[j],nums[left],nums[right]));
while(left < right && nums[left]==nums[left+1]) left++;
while(left < right && nums[right]==nums[right-1]) right--;
left++;
right--;
}
}
}
}
return result;
}
}
344. 反转字符串
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s
的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
示例 1:
输入:s = ["h","e","l","l","o"] 输出:["o","l","l","e","h"
class Solution {
public void reverseString(char[] s) {
int i = 0;
int j = s.length - 1;
while(i<j){
//定义临时变量
char temp = s[i];
s[i] = s[j];
s[j] = temp;
i++;
j--;
}
}
}
541. 反转字符串II
给定一个字符串 s
和一个整数 k
,从字符串开头算起,每计数至 2k
个字符,就反转这 2k
字符中的前 k
个字符。
- 如果剩余字符少于
k
个,则将剩余字符全部反转。 - 如果剩余字符小于
2k
但大于或等于k
个,则反转前k
个字符,其余字符保持原样。
示例 1:
输入:s = "abcdefg", k = 2 输出:"bacdfeg"
class Solution {
public String reverseStr(String s, int k) {
char ch[] = s.toCharArray(); //将字符串转换成数组
for(int i = 0; i < ch.length; i+= 2*k){
int left = i;
//确定要反转的位置
int right = Math.min(ch.length - 1,left + k - 1);
while(left < right){
char temp = ch[left];
ch[left] = ch[right];
ch[right] = temp;
left++;
right--;
}
}
return new String(ch);
}
}
28.找出字符串中第一个匹配的下标
给你两个字符串 haystack
和 needle
,请你在 haystack
字符串中找出 needle
字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle
不是 haystack
的一部分,则返回 -1
。
示例 1:
输入:haystack = "sadbutsad", needle = "sad" 输出:0 解释:"sad" 在下标 0 和 6 处匹配。 第一个匹配项的下标是 0 ,所以返回 0 。
示例 2:
输入:haystack = "leetcode", needle = "leeto" 输出:-1 解释:"leeto" 没有在 "leetcode" 中出现,所以返回 -1 。
class Solution {
public int strStr(String haystack, String needle) {
int next[] = new int[needle.length()];
getNext(next,needle);
int j = 0;
for(int i = 0; i < haystack.length(); i++ ){
while(j > 0 && haystack.charAt(i) != needle.charAt(j)) j = next[j-1];
if(haystack.charAt(i) == needle.charAt(j)) j++;
if(j == needle.length())
return i-needle.length()+1;
}
return -1;
}
//基于前缀表(不减1)
public void getNext(int[] next, String s){
int j = 0;//前缀末尾
next[0] = 0;
for(int i = 1; i < s.length();i++){
while(j >0 && s.charAt(j) != s.charAt(i)) j =next[j-1];
if(s.charAt(j) == s.charAt(i)) j++;
next[i] = j;
}
}
}
459.重复的子字符串
给定一个非空的字符串 s
,检查是否可以通过由它的一个子串重复多次构成。
示例 1:
输入: s = "abab" 输出: true 解释: 可由子串 "ab" 重复两次构成。
示例 2:
输入: s = "aba" 输出: false
class Solution {
public boolean repeatedSubstringPattern(String s) {
/**
思路:KMP算法
1.初始化
2.构造next数组
3.判断子串构成
*/
//1.初始化
char[] chars = s.toCharArray();
int[] next = new int[s.length()];
int j = 0;
int len = s.length();
int count = 0;
//2.构造next数组
for(int i =1; i < s.length(); i++){
while(j >0 && s.charAt(i) != s.charAt(j)) j = next[j-1];
if(s.charAt(i) == s.charAt(j)) j++;
next[i] =j;
}
//2.构造next数组
if(next[len-1] >0 && len % (len-next[len-1])== 0){
return true;
}
return false;
}
}