双指针
public int[] twoSum(int[] numbers, int target) {
int i = 0, j = numbers.length - 1;
while (i < j) {
int sum = numbers[i] + numbers[j];
if (sum == target) {
return new int[] {i + 1, j + 1};
}
else if (sum < target) {
i++;
}
else {
j--;
}
}
return null;
}
2.两数平方和
Input: 5
Output: True
Explanation: 1 * 1 + 2 * 2 = 5
题目描述:判断一个数是否为两个数的平方和。
public boolean judgeSquareSum(int c) {
int i = 0, j = (int) Math.sqrt(c);
while (i <= j) {
int powSum = i * i + j * j;
if (powSum == c) {
return true;
} else if (powSum > c) {
j--;
} else {
i++;
}
}
return false;
}
3.反转字符串中的元音字符
Given s = "leetcode", return "leotcede".
使用双指针指向待反转的两个元音字符,一个指针从头向尾遍历,一个指针从尾到头遍历。
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){
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);
}
4.回文字符串
Input: "abca"
Output: True
Explanation: You could delete the character 'c'.
题目描述:可以删除一个字符,判断是否能构成回文字符串。
public boolean validPalindrome(String s){
for(int i=0;j=s.length()-1;i<j;i++,j--){
if(s.charAt(i)!=s.char(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;
}
5.归并两个有序数组
Input:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3
Output: [1,2,2,3,5,6]
题目描述:把归并结果存到第一个数组中。
需要从尾开始遍历,否则在nums1上归并得到的值会覆盖还未进行归并比较的值。
public void merge(int[] nums1,int m,int[] nums2,int n){
int index1=m-1,index2=n-1;
int indexMerge=m+n-1;
while(index1>=0||index2>=0){
if(index1<0){
nums1[indexMerge--]=nums2[index2--];
}else if(index2<0){
nums1[indexMerge--]=nums1[index1--];
}else if(nums1[index1]>nums2[index2]){
num1[indexMerge--]=nums1[index1--];
}else{
nums1[indexMerge--]=nums[index2--];
}
}
}
6.判断链表是否存在环
使用双指针,一个指针每次移动一个节点,一个指针每次移动两个节点,如果存在环,那么这两个指针一定相遇。
public boolean hasCycle(ListNode head){
if(head==null){
return false;
}
ListNode L1=head;L2=head.next;
while(L1!=null&&L2!=null&&L2.next!=null){
if(L1==L2){
return true;
}
L1=L1.next;
L2=L2.next.next;
}
return false;
}
7.最长子序列
Input:
s = "abpcplea", d = ["ale","apple","monkey","plea"]
Output:
"apple"
题目描述:删除s中的一些字符,使它构成字符串列表d中的一个字符串,找出能构成最长的字符串。如果有多个相同长度的结果,返回字典序的最小字符串。
通过删除字符串s中的一个字符能得到字符串t,可以认为t是s的子序列,可以使用双指针来判断一个字符串是否为另一个字符串的子序列。
public String finalLongestWord(String s,List<String> d){
String longestWord="";
for(String target:d){
int L1=longestWord.length(),L2=target.length();
if(L1>L2||(L1==L2&&longestWord.compareTo(target)<0)){
continue;
}
if(isSubstr(s,target)){
longestWord=target;
}
}
return longestWOrd;
}
private boolean isSubstr(String s,String target){
int i=0;j=0;
while(i<s.length()&&j<target.length()){
if(s.charAt(i)==target.charAt(j)){
j++;}
i++;
}
return j==target.length();
}