双指针思想

双指针:

双指针主要用于遍历数组,两个指针指向不同的元素,从而协同完成任务。

 

1.有序数组的 Two Sum

Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2

题目描述:在有序整数数组中,找到两个和为目标值得元素并封装成数组返回。

  思路:

  使用双指针,一个指针指向值较小的元素,一个指针指向值较大的元素。指向较小元素的指针从头向尾遍历,指向较大元素的指针从尾向头遍历。

  • 如果两个指针指向元素的和 sum == target,那么得到要求的结果;
  • 如果 sum > target,移动较大的元素,使 sum 变小一些;
  • 如果 sum < target,移动较小的元素,使 sum 变大一些。
 1 private static int[] find(int[] arr, int target) {
 2         int low = 0;
 3         int high = arr.length - 1;
 4         int[] newArr = new int[2];
 5         while (low < high) {
 6             if (arr[low] + arr[high] < target) {
 7                 low++;
 8             } else if (arr[low] + arr[high] > target) {
 9                 high--;
10             } else {
11                 return new int[] { arr[low], arr[high] };
12             }
13         }
14         return null;
15     }

 

 

2.两数平方和

Input: 5
Output: Tru
Explanation: 1 * 1 + 2 * 2 = 5

题目描述:设计一个函数,实现:判断输入的一个数是否为两个数的平方和

思路:从数学上看,左指针的平方加上右指针的平方要等于target。则左指针选从0开始,右指针选数学上(int) Math.sqrt(c),即向下取整。

 

 1 private static boolean find(int c) {
 2         int low = 0;
 3         int high = (int) Math.sqrt(c);
 4         while (low <= high) {
 5             int temp = low * low + high * high;
 6             if (temp < c)
 7                 low++;
 8             else if (temp > c)
 9                 high--;
10             else
11                 return true;
12         }
13         return false;
14     }

 

 

3.反转字符串中的元音字符

题目描述:反转字符串中的元音字符串。

例子:Given s = "leetcode", return "leotcede".

思路:使用双指针指向待反转的两个元音字符,一个指针从头向尾遍历,一个指针从尾到头遍历。

 1 public class test3 {
 2     final static List<Character> list = new ArrayList<>(
 3             Arrays.asList('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'));//全局变量
 4 
 5     public static void main(String[] args) {
 6         String string = "aeiouhhhae";
 7         System.out.println(reverse(string));
 8     }
 9 
10     private static String reverse(String string) {
11         char[] newArr = new char[string.length()];
12         int low = 0;
13         int high = string.length() - 1;
14         while (low <= high) {
15             char a = string.charAt(low);
16             char b = string.charAt(high);
17         
18             if (!list.contains(a)) {
19                 newArr[low] = a;
20                 low++;
21             } else if (!list.contains(b)) {
22                 newArr[high] = b;
23                 high--;
24             } else {
25                 char temp = newArr[low];
26                 newArr[low++] = b;
27                 newArr[high--] = a;
28             }
29         }
30         return new String(newArr);
31     }
32 }

 

 

4.回文字符串

题目描述:对于字符串,判断是否是回文串,可以最多删掉一个字符

例子:
Input: "abca" Output: True Explanation: You could delete the character 'c'.
思路:当第一次用左右指针遍历时碰到不相等的情况时,调用函数,在该函数中只要不是回文串就返回false
 1 private static boolean find(String str) {
 2         int i = -1, j = str.length();
 3         while (++i < --j) {
 4             if (str.charAt(i) != str.charAt(j)) {
 5                 return isFind(str, i + 1, j) || isFind(str, i, j - 1);
 6             }
 7         }
 8         return true;
 9 
10     }
11 
12     private static boolean isFind(String str, int i, int j) {
13         while (i++ < j--) {
14             if (str.charAt(i) != str.charAt(j))
15                 return false;
16         }
17         return true;
18     }

 

 

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 上归并得到的值会覆盖还未进行归并比较的值。

 1 private static int[] find(int[] nums1, int n, int[] nums2, int m) {
 2 
 3         int i = n - 1, j = m - 1;
 4         int index = nums1.length - 1;
 5         while (i >= 0 || j >= 0) {
 6             if (i == -1) {
 7                 nums1[index--] = nums2[j--];
 8             } else if (j == -1) {
 9                 nums1[index--] = nums1[i--];
10             } else
11                 nums1[index--] = nums1[i] > nums2[j] ? nums1[i--] : nums2[j--];
12         }
13         return nums1;
14 
15     }

 

 

6.判断链表是否存在环

题目描述:判断链表是否存在环

思路:使用双指针,一个指针每次移动一个节点,一个指针每次移动两个节点,如果存在环,那么这两个指针一定会相遇。就像两个人不同速度在操场上跑步必定会相遇一样。

 1 private static boolean find(node head) {
 2         if (head == null)
 3             return true;
 4         node temp1 = head;
 5         node temp2 = head;
 6         while (temp1 != null && temp2 != null && temp2.next != null) {
 7             temp1 = temp1.next;
 8             temp2 = temp2.next.next;
 9             if (temp1 == temp2)
10                 return true;
11         }
12         return false;
13 
14     }

 

 

7.最长子序列

Input:
s = "abpcplea", d = ["ale","apple","monkey","plea"]

Output:
"apple"

题目描述:删除 s 中的一些字符,使得它构成字符串列表 d 中的一个字符串,找出能构成的最长字符串。如果有多个相同长度的结果,返回字典序的最小字符串。

 1 private static String findLongestWord(String s, List<String> d) {
 2         String longestWord = "";
 3         for (String target : d) {//遍历list,判断元素与string 是否满足要求。
 4             int l1 = longestWord.length(), l2 = target.length();
 5             if (l1 > l2 || (l1 == l2 && longestWord.compareTo(target) < 0)) {
 6                 continue;
 7             }
 8             if (isValid(s, target)) {
 9                 longestWord = target;//满足要求
10             }
11         }
12         return longestWord;
13     }
14 
15     
16     /**
17      * 判断一个字符串删除一些字符后是否能与后一个字符串相等
18      * @param s
19      * @param target
20      * @return
21      */
22     private static boolean isValid(String s, String target) {
23         int i = 0, j = 0;
24         while (i < s.length() && j < target.length()) {
25             if (s.charAt(i) == target.charAt(j)) {
26                 j++;
27             }
28             i++;
29         }
30         return j == target.length();
31     }
32 }

 

 

转载于:https://www.cnblogs.com/zclun/p/10650734.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值