演算法-雙指標
心灰盡,有發未全僧。
簡介:演算法-雙指標
一、和為S 的兩個數字
1、題目描述
在有序陣列中找出兩個數,使得和為給定的數 S。如果有多對數字的和等於 S,輸出兩個數的乘積最小的。
2、解題思路
使用雙指標,一個指標指向元素較小的值,一個指標指向元素較大的值。指向較小元素的指標從頭向尾遍歷,指向較大元素的指標從尾向頭遍歷。
- 如果兩個指標指向元素的和 sum == target,那麼這兩個元素即為所求。
- 如果 sum > target,移動較大的元素,使 sum 變小一些;
- 如果 sum < target,移動較小的元素,使 sum 變大一些。
3、程式碼示例
1 import java.util.ArrayList;
2 public class Solution {
3 public ArrayList<Integer> FindNumbersWithSum(int [] array, int sum) {
4 ArrayList<Integer> list = new ArrayList<>();
5 int i = 0;
6 int j = array.length - 1;
7 while(i < j){
8 if(array[i] + array[j] == sum){
9 list.add(array[i]);
10 list.add(array[j]);
11 break;
12 }else if(array[i] + array[j] < sum){
13 i++;
14 }else{
15 j--;
16 }
17 }
18 return list;
19 }
20 }
二、和為S 的連續正數序列
1、題目描述
輸出所有和為 S 的連續正數序列。例如和為 100 的連續序列有:
[9, 10, 11, 12, 13, 14, 15, 16]
[18, 19, 20, 21, 22]
2、解題思路
字首和
對於求一個區間和,一貫的優化技巧是使用字首和。比如:
sum[i]表示前i個數的和。比如sum[1] = 1
,表示前一個數的和為1
,sum[2] = 3
, 表示前2
個數的和為3。
現在我們要求區間[2,4]
表示求第2,3,4
個數的和,就等於sum[4] - sum[1] = 9
在程式碼中用一個變數來模擬這個字首和。
1 import java.util.ArrayList;
2 public class Solution {
3 public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
4 ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
5 for(int i = 1; i < sum; i++){
6 int temp = 0;
7 int j = i;
8 while(temp < sum){
9 temp += j;
10 j++;
11 }
12 if(temp == sum){
13 // 滿足條件則拼裝資料
14 ArrayList<Integer> list = new ArrayList<Integer>();
15 for(int k = i; k < j; k++){
16 list.add(k);
17 }
18 result.add(list);
19 }
20 }
21 return result;
22 }
23 }
三、翻轉單詞順序列
1、題目描述
Input:
"I am a student."
Output:
"student. a am I"
2、解題思路
藉助一些Java 自帶的API 就很容易實現。
1 import java.util.*;
2
3 public class Solution {
4 public String ReverseSentence(String str) {
5 String[] split = str.split(" ");
6 List<Object> list = new ArrayList<>();
7 StringBuilder sb = new StringBuilder();
8 for(int i = 0; i < split.length; i++){
9 list.add(split[i]);
10 }
11 Collections.reverse(list); // 藉助集合翻轉API
12 Iterator<Object> iterator = list.iterator();
13 while (iterator.hasNext()){
14 sb.append(iterator.next()).append(" ");
15 }
16 return sb.toString().trim(); // 除去最後一個append 加上去的空格
17 }
18 }
四、左旋轉字串
1、題目描述
將字串 S 從第 K 位置分隔成兩個子字串,並交換這兩個子字串的位置。
Input:
S="abcXYZdef"
K=3
Output:
"XYZdefabc"
2、解題思路
使用Java API 的substring 就很簡單了。
1 public class Solution {
2 public String LeftRotateString(String str, int n) {
3 int length = str.length();
4 if(n > length){
5 return "";
6 }
7 String substring1 = str.substring(0, n); // substring 左閉右開
8 String substring2 = str.substring(n);
9 return substring2 + substring1;
10 }
11 }
心灰盡
有發未全僧