167.有序数组Two Sum
使用双指针,一个指向最左边,一个指向最右边,判断与目标target的大小关系
- 如果l+r>target,右边的r向左移
- 如果l+r<target,左边的l向右移
public int[] twoSum(int[] numbers, int target) {
int []res=new int[2];
int l=0,r=numbers.length-1;
while(l<r){
if(numbers[l]+numbers[r]>target){
r--;
}else if(numbers[l]+numbers[r]<target){
l++;
}else{
res[0]=l+1;
res[1]=r+1;
return res;
}
}
return new int[0];
}
633. 平方数之和
题目:给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a2 + b2 = c 。
思路:双指针,左边从0开始,右边取c的开平方,
- 如果ll+rr>target,r向左移
- 如果ll+rr<target,l向右移
public boolean judgeSquareSum(int c) {
int r=(int)Math.sqrt(c),l=0;
while(l<=r){
if(r*r+l*l<c){
l++;
}else if(r*r+l*l>c){
r--;
}else {
return true;
}
}
return false;
}
345. 反转字符串中的元音字母
题目:编写一个函数,以字符串作为输入,反转该字符串中的元音字母。
思路:双指针,从两边开始
- 遇到两边都是元音字母就交换,然后移动
- 一边是一边不是,不是的那边移动
- 都不是,都移动
public String reverseVowels(String s) {
char[]ch=s.toCharArray();
int l=0,r=s.length()-1;
while(l<r){
if(isyuan(ch[l])&&isyuan(ch[r])){
char temp=ch[l];
ch[l]=ch[r];
ch[r]=temp;
r--;
l++;
}else if(isyuan(ch[l])){
r--;
}else if(isyuan(ch[r])){
l++;
}else{
r--;
l++;
}
}
return String.valueOf(ch);
}
public boolean isyuan(char c){
if(c=='a'||c=='e'||c=='i'||c=='o'||c=='u'||c=='A'||c=='E'||c=='I'||c=='O'||c=='U'){
return true;
}
return false;
}
680. 验证回文字符串 Ⅱ
题目:给定一个非空字符串 s,最多删除一个字符。判断是否能成为回文字符串。
思路:从两边遍历,如果相等就向中间移动,如果不相等,就判断去掉一个字符后能否相等(只要有一边能相等即可)z
public boolean validPalindrome(String s) {
int l=0,r=s.length()-1;
while(l<r){
if(s.charAt(l)==s.charAt(r)){
l++;
r--;
}else{
return isPalindrome(s,l,r-1)||isPalindrome(s,l+1,r);
}
}
return true;
}
public boolean isPalindrome(String s,int l,int r) {
while(l<r){
if(s.charAt(l)==s.charAt(r)){
l++;
r--;
}else{
return false;
}
}
return true;
}
88. 合并两个有序数组
题目:给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。
思路:关键是先将较大的数填到nums1末尾
public void merge(int[] nums1, int m, int[] nums2, int n) {
int l=0,r=m+n-1;
while(m>0&&n>0) {
if(nums1[m-1]>=nums2[n-1]){
nums1[r]=nums1[m-1];
m--;
}else {
nums1[r]=nums2[n-1];
n--;
}
r--;
}
if(n>0){
for (int i = 0; i <n; i++) {
nums1[i]=nums2[i];
}
}
}
141. 环形链表
题目:给定一个链表,判断链表中是否有环。
思路:快慢指针,如果两个指针最终相遇,则表明有环。
public boolean hasCycle(ListNode head) {
if(head==null)return false;
ListNode p=head,q=head.next;
while(p!=null&&q!=null&&q.next!=null){
if(p==q)return true;
p=p.next;
q=q.next.next;
}
return false;
}
524. 通过删除字母匹配到字典里最长单词
题目:给定一个字符串和一个字符串字典,找到字典里面最长的字符串,该字符串可以通过删除给定字符串的某些字符来得到。如果答案不止一个,返回长度最长且字典顺序最小的字符串。如果答案不存在,则返回空字符串。
思路:先写个函数判断s1是不是s的子串,如果是的话就加入hashmap中,map的键是s1的长度,值是s1,如果字典中1.没有那个键2.有键但是值的字典顺序大于s1,就将s1加入字典
坑:字典顺序不是指在链表里的顺序,是它本身的顺序 ab<ba 用s1.compareTo(s2)判断,s1比s2靠前,则返回一个负值
public static String findLongestWord(String s, List<String> d) {
int max=0;
Map<Integer,String>map=new HashMap<>();
for (String s1 : d) {
if(isSubString(s,s1)){
int key=s1.length();
if((map.get(key)==null)||(map.get(key)!=null&&s1.compareTo(map.get(key))<0)){
map.put(key,s1);
}
if(max<key)max=key;
}
}
return map.get(max)==null?"":map.get(max);
}
public static boolean isSubString(String s1,String s2){
int i=0,j=0;
while(j<s2.length()&&i<s1.length()){
if(s1.charAt(i)==s2.charAt(j)){
i++;
j++;
}else{
i++;
}
}
return j == s2.length();
}