604. Window Sum:点击打开链接

例如:[1,2,7,8,5], k=3

sum[0]=nums[0]+nums[1]+nums[2]=10

sum[1]=sum[0]-nums[0]+nums[0+3]=17,也就是说sum[1]=10-1+8

sum[2]=sum[1]-nums[1]+nums[1+3]=20,也就是说sum[2]=17-2+5

窗口向后滑动,要减去(滑出窗口里的值),同时加上(滑入窗口里的值)

public class Solution {/*** @param nums a list of integers.* @return the sum of the element inside the window at each moving.*/public int[] winSum(int[] nums, int k) {if(nums==null || nums.length==0){return new int[0];}if(k<=0){return new int[0];}int[] sum=new int[nums.length-k+1];               for(int i=0;i<k;i++){                                //i<ksum[0]+=nums[i];}for(int i=1;i<sum.length;i++){                       //i<sum.length,不然数组越界异常sum[i]=sum[i-1]-nums[i-1]+nums[i-1+k];}return sum;}
}

539. Move Zeros:点击打开链接

public class Solution {/*** @param nums an integer array* @return nothing, do this in-place*/public void moveZeroes(int[] nums) {int j=0;for(int i=0;i<nums.length;i++){     //i从头开始遍历,当值不为0就和第一个交换位置,再有值不为0,和第一个的后一个交换if(nums[i]!=0){                 //即使开始的值不为0,也不影响,因为相当于自己和自己交换int temp=nums[i];           //例如:[1,2,0,3,4],开始交换的时候1,2的位置不变,值为3的时候和0交换,4同理nums[i]=nums[j];nums[j]=temp;j++;}}}
}
public class Solution {/*** @param nums an integer array* @return nothing, do this in-place*/public void moveZeroes(int[] nums) {    //为什么这种做法不行?int j=nums.length;                  //i从头开始遍历,当值为0就和最后一个数交换位置,再有值为0,和最后一个的前一个交换for(int i=0;i<nums.length;i++){     //因为这种做法可能最后一个位置的值是0if(nums[i]==0){                 //例如:[0,1,0,1,3,0],开始交换的时候只是头和尾两个0交换了位置,所以不对 int temp=nums[i];nums[i]=nums[j];nums[j]=temp;j--;}}}
}

521.Remove Duplicates from Sorted Array:点击打开链接

public class Solution {/*** @param nums an array of integers* @return the number of unique integers*/public int deduplication(int[] nums) {   //例如:[1,3,1,4,4,2]if(nums==null || nums.length==0){return 0;}Arrays.sort(nums);                   //[1,1,1,2,3,4,4]            int index=1;for(int i=1;i<nums.length;i++){      //就让第一个值不动,从第二个值开始,依次与前一个值比较if(nums[i]!=nums[i-1]){          //如果两者不相等,后者值和index++位置的值交换位置nums[index++]=nums[i];}}return index;}
}
public class Solution {/*** @param nums an array of integers* @return the number of unique integers*/public int deduplication(int[] nums) {  //方法二if(nums==null || nums.length==0){return 0;}Arrays.sort(nums);                  //解题前要看题目给出的数组是不是有序数组,不是的话要排序int i=0;                            //是否排序也要看题目要求,如果让输出符合条件的索引,不可以排序for(int n:nums){if(i<1 || n!=nums[i-1]){nums[i++]=n;}}return i;}
}

101. Remove Duplicates from Sorted Array II:点击打开链接

思路:当i=0时,nums[0]还是本身

当i=1时,nums[1]也还是本身,因为不管nums[1]是否等于nums[0]都没关系,因为题目说最多可以有两个duplicates

从i=2开始,开始判断nums[i-2]!=n,也就是说nums[0]!=nums[2],其实就是判断这个数与否等于它前两位的那个数,

如果不等于,符合题目要求,当前数有效,不移除。

public class Solution {/*** @param A: a array of integers* @return : return an integer*/public int removeDuplicates(int[] nums) {if(nums==null || nums.length==0){return 0;}int i=0;                                         //例如{3,3,4,5,5,6}for(int n:nums){                                 //在i=0,i=1的时候已经和数组用n表示的前两个数比较过if(i<2 || n!=nums[i-2]){                     //i=2的时候,n!=nums[i-2]表示的是4!=nums[0]nums[i++]=n;                            }}return i;}
}

8.Rotate String:点击打开链接

例如:char[] str=[a,b,c,d,e,f,g],offset=3

Output:    [e,f,g,a,b,c,d]

三步翻转法:

1. [g,f,e,d,c,b,a],整个大翻转

2. [e,f,g,d,c,b,a], e,f,g翻转

3. [e,f,g,a,b,c,d], a,b,c,d翻转

注意:先整个大翻转的必要性,一般来说,由于往前放的位数少,因此先进行整个大翻转会省时

当然也可以先局部翻转,再整个大翻转

要看具体题目要求,是要在原来有序的数组上后面几个元素翻转到前面,还是已经翻转好的要恢复有序数组

也就是说,是要[a,b,c,d,e,f,g]->[e,f,g,a,b,c,d],还是[e,f,g,a,b,c,d]恢复成[a,b,c,d,e,f,g]

public class Solution {/*** @param str: an array of char* @param offset: an integer* @return: nothing*/public void rotateString(char[] str, int offset) {if(offset==0){return;}if(str==null || str.length==0){return;}int n=str.length;offset=offset%n;reverse(str,0,n-1);reverse(str,0,offset-1);reverse(str,offset,n-1);}private void reverse(char[] str,int start,int end){while(start<end){char temp=str[start];   //char tempstr[start]=str[end];                       str[end]=temp;start++;end--;}}
}

39.Recover Rotated Sorted Array :点击打开链接

题意:这题就是要恢复成有序arraylist,例如:[4,5,1,2,3]->[1,2,3,4,5]

思路:从5和1这个位置入手,遍历整个list的值,只要前一个值比后一个值大,就找到了5和1,然后j进行三步翻转

注意:reverse方法对一个arraylist进行reverse,因此用了方法arraylist.set()

public class Solution {/*** @param nums: The rotated sorted array* @return: void*/public void recoverRotatedSortedArray(ArrayList<Integer> nums) {if(nums==null || nums.size()==0){return;}int k=0;for(int i=0;i<nums.size()-1;i++){if(nums.get(i)>nums.get(i+1)){k=i;reverse(nums,0,k);reverse(nums,k+1,nums.size()-1);reverse(nums,0,nums.size()-1);}}}private void reverse(ArrayList<Integer> nums,int start,int end){while(start<end){int temp=nums.get(start);nums.set(start,nums.get(end));    //nums.set()nums.set(end,temp);start++;end--;}}
}

56.Two Sum:点击打开链接

下面就是经典题型Two Sum和它的一系列follow ups

对于Two Sum一般有两种做法:HashMap和Two Pointers

public class Solution {/** @param numbers : An array of Integer* @param target : target = numbers[index1] + numbers[index2]* @return : [index1 + 1, index2 + 1] (index1 < index2)*/public int[] twoSum(int[] numbers, int target) {       //HashMap方法int[] result=new int[2];if(numbers==null ||numbers.length==0){return result;}Map<Integer,Integer> map=new HashMap<>();          //例如:[2,7,11,15],target=9for(int i=0;i<numbers.length;i++){if(!map.containsKey(target-numbers[i])){       //遍历数组,一开始nums[0]=2,map里没有7,放入<2,0>map.put(numbers[i],i);}else{                                         //往下遍历到nums[1]=7,map里有2,result[0]=map.get(target-numbers[i])+1;    //就把2和7所对应的索引加入到result list里result[1]=i+1;                             //由于题目要求result不是zero-based,所以每个索引值+1}}return result;}
}

608.Two Sum-Input array is Sorted:点击打开链接

public class Solution {/** @param nums an array of Integer* @param target = nums[index1] + nums[index2]* @return [index1 + 1, index2 + 1] (index1 < index2)*/public int[] twoSum(int[] nums, int target) {         //双指针法:适合可以sort的数组int[] result=new int[2];if(nums==null || nums.length==0){return result;}int start=0;int end=nums.length-1;while(start<end){                                 //因为最后要有start和end两个数,因此不能start<=endif(nums[start]+nums[end]<target){   start++;}else if(nums[start]+nums[end]>target){end--;}else{result[0]=start+1;                        //注意好题目要求是non zero-based,还是zero-basedresult[1]=end+1;return result;}}return null;}
}

607.Two Sum-Data Structure Design:点击打开链接

public class TwoSum {                                    //只能使用HashMap的private List<Integer> list=null;private Map<Integer,Integer> map=null;public TwoSum(){list=new ArrayList<>();map=new HashMap<>();}// Add the number to an internal data structure.public void add(int number) {// Write your code hereif(!map.containsKey(number)){map.put(number,1);list.add(number);}else{map.put(number,map.get(number)+1);}}// Find if there exists any pair of numbers which sum is equal to the value.public boolean find(int value) {for(int i=0;i<list.size();i++){int nums1=list.get(i);int nums2=value-nums1;if(nums1==nums2 && map.get(nums1)>1){return true;}if(nums1!=nums2 && map.containsKey(nums2)){return true;}}return false;}
}// Your TwoSum object will be instantiated and called as such:
// TwoSum twoSum = new TwoSum();
// twoSum.add(number);
// twoSum.find(value);

587.Two Sum-Unique pairs:点击打开链接

public class Solution {/*** @param nums an array of integer* @param target an integer* @return an integer*/public int twoSum6(int[] nums, int target) {if(nums==null || nums.length<0){return 0;}Arrays.sort(nums);int start=0,end=nums.length-1;int count=0;while(start<end){if(nums[start]+nums[end]==target){start++;end--;count++;                                          while(start<end && nums[start]==nums[start-1]){   //当有一对和为target的数时,看start的后面的数是否与start等start++;                                      //如果等,就要往前走以便略过这个相同的数}while(start<end && nums[end]==nums[end+1]){       //也要看end的前面的数时候与end等end--;                                        //如果等,就要end--方式向前走以便略过这个相同的数}}else if(nums[start]+nums[end]>target){end--;}else{start++;}}return count;}
}

609. Two Sum-Less than or equal to target: 点击打开链接

例如:[2,7,11,15],target=24

思路:当2+15<24,15是最大值都小于target了,2+7,2+11一定也小于,两数对应的索引相减3-0=3,这段区间有3对数符合要求,start++

再看[2,7,11,15]这段区间,同理有3-1=2对数符合要求,start++

再看[2,7,11,15]这段区间, 11+15>target,end--

public class Solution {/*** @param nums an array of integer* @param target an integer* @return an integer*/public int twoSum5(int[] nums, int target) {if(nums==null || nums.length==0){return 0;}Arrays.sort(nums);int count=0;int start=0,end=nums.length-1;while(start<end){if(nums[start]+nums[end]<=target){count+=end-start;start++;}else{end--;}}return count;}
}

443.Two Sum-Greater than target:点击打开链接

public class Solution {/*** @param nums: an array of integer* @param target: an integer* @return: an integer*/public int twoSum2(int[] nums, int target) {   //和小于等于target的正好相反if(nums==null ||nums.length==0){return 0;}Arrays.sort(nums);int count=0;int start=0,end=nums.length-1;while(start<end){if(nums[start]+nums[end]<=target){     //如果小于等于target,start++start++;}else{                                 //直到大于target,这段区间符合条件的对数是:区间前后索引之差        count+=end-start;end--;                             //end--}}return count;}
}

610.Two Sum-Difference equals to target:点击打开链接

例如:[2,7,15,14],target=5

思路:遍历数组,但是每个值都要查看nums[i]+target和nums[i]-target 两种情况

public class Solution {/** @param nums an array of Integer* @param target an integer* @return [index1 + 1, index2 + 1] (index1 < index2)*/public int[] twoSum7(int[] nums, int target) {int[] result=new int[2];if(nums==null || nums.length==0){return result;}Map<Integer,Integer> map=new HashMap<>();for(int i=0;i<nums.length;i++){int diff1=nums[i]-target;int diff2=nums[i]+target;if(!map.containsKey(diff1) && !map.containsKey(diff2)){map.put(nums[i],i);}else if(map.containsKey(diff1)){result[0]=map.get(diff1)+1;result[1]=i+1;break;}else if(map.containsKey(diff2)){result[0]=map.get(diff2)+1;result[1]=i+1;break;}}return result;}
}

57. 3Sum:点击打开链接

例如:[-1,0,1,2,-1,-4]

思路:a+b+c=0,-a=b+c

遍历数组里的每一个数nums[i],对于每一个数,都从i+1~nums.length-1区间来找另外两个数,

使得-nums[i]=nums[i+1]+nums[nums.length-1],也就是nums[i]+nums[i+1]+nums[nums.length-1]=0

注意:1. 用Two Pointers方法一定要先Arrays.sort()数组

2. 对于nums[i],nums[i+1]和nums[length-1]都要判断是不是与前一个数相等

public class Solution {/*** @param numbers : Give an array numbers of n integer* @return : Find all unique triplets in the array which gives the sum of zero.*/public ArrayList<ArrayList<Integer>> threeSum(int[] numbers) {ArrayList<ArrayList<Integer>> result=new ArrayList<>();if(numbers==null || numbers.length<3){                 //只要numbers.length<3就不符合题意了return result;}Arrays.sort(numbers);for(int i=0;i<numbers.length-1;i++){if(i>0 && numbers[i]==numbers[i-1]){               //对于每一个a都要判断是不是和前一个相等continue;}int target=-numbers[i];int start=i+1;int end=numbers.length-1;twoSum(numbers,start,end,target,result);}return result;}private void twoSum(int[] nums,int start,int end,int target,ArrayList<ArrayList<Integer>> result){while(start<end){if(nums[start]+nums[end]==target){ArrayList<Integer> list=new ArrayList<>();list.add(-target);list.add(nums[start]);list.add(nums[end]);result.add(list);start++;end--;while(start<end && nums[start]==nums[start-1]){     start++;}while(start<end && nums[end]==nums[end+1]){end--;}}else if(nums[start]+nums[end]<target){start++;}else{end--;}}}
}

例如:[1,1,2,3,4,5,6],target=9

1. i从0向后遍历

2. 第一轮i=0,start=1,end=6,因为开始小于9,所以start++到start=2,此时1+2+6=9,

完成装到result后,start和end还会移动,找其他满足条件的组合,以上是一个完整的第一轮,然后才开始第二轮

3. 第二轮i=1,start=1,end=6,此时1+2+6=9

因为被遍历的i与它前一个数相等,因此会以continue的方法跳出本次,因为这样的情况下会输出重复组合

4. 第三轮i=2

public class Solution {/*** @param numbers : Give an array numbers of n integer* @return : Find all unique triplets in the array which gives the sum of zero.*/public ArrayList<ArrayList<Integer>> threeSum(int[] numbers) {       //方法二:直接看当前三个数的和是不是等于0ArrayList<ArrayList<Integer>> result=new ArrayList<>();          //个人感觉这个方法更直接,更容易弄懂if(numbers==null || numbers.length<3){return result;}Arrays.sort(numbers);for(int i=0;i<numbers.length-1;i++){if(i>0 && numbers[i]==numbers[i-1]){                         //如果i重复continue;                                                //跳出本次i,进入for循环里的下一个i}int start=i+1;int end=numbers.length-1;while(start<end){int sum=numbers[i]+numbers[start]+numbers[end];if(sum==0){ArrayList<Integer> list=new ArrayList<>();list.add(numbers[i]);list.add(numbers[start]);list.add(numbers[end]);result.add(list);start++;end--;while(start<end && numbers[start]==numbers[start-1]){//如果start重复start++;}while(start<end && numbers[end]==numbers[end+1]){    //如果end重复end--;}}else if(sum<0){start++;}else{end--;}}}return result;}
}

923. 3Sum With Multiplicity

 public int threeSumMulti(int[] A, int target) {int mol = 1000000007; // 如果写成10^9+7的形式,就过不了,Bitwise Operators Arrays.sort(A);int res = 0;Map<Integer, Long> map = new HashMap<>();for (int i = 0; i < A.length; ++i) {map.put(A[i], map.getOrDefault(A[i], 0l) + 1l);}for (int i = 0; i < A.length; i++) {if (i > 0 && A[i] == A[i - 1]) {continue;}int start = i + 1, end = A.length - 1;while (start < end) {if (A[i] + A[start] + A[end] < target) {start++;}else if (A[i] + A[start] + A[end] > target) {end--;}else {if (A[i] == A[start] && A[start] == A[end]) {res += (map.get(A[i])) * (map.get(A[i]) - 1) * (map.get(A[i]) - 2) / 6 % mol;}else if (A[i] == A[start]) {res += (map.get(A[i])) * (map.get(A[i]) - 1) / 2 * (map.get(A[end])) % mol;}else if (A[start] == A[end]) {res += (map.get(A[i])) * (map.get(A[start])) * (map.get(A[start]) - 1) / 2 % mol;}else {res += map.get(A[i]) * map.get(A[start]) * map.get(A[end]) % mol;}start++;end--;while (start<end && A[start] == A[start-1]){start++;}while (start<end && A[end] == A[end+1]) {end--;}                  }}}return res;

259. 3Sum Smaller

Given an array of n integers nums and a target, find the number of index triplets i, j, k with 0 <= i < j < k < nthat satisfy the condition nums[i] + nums[j] + nums[k] < target.

Example:

Input: nums = [-2,0,1,3], and target = 2
Output: 2
Explanation: Because there are two triplets which sums are less than 2:[-2,0,1][-2,0,3]

Note: 以[-2, 0, 1, 3]作为example , nums[i] =-2,,nums[start]=0,,nums[end]=3,,当-2+0+3<target时,如果采用start++来判断, 此时nums[start]=1, 所以走向一直是start向右移动,会漏掉end应该向左移动的cases

class Solution {public int threeSumSmaller(int[] nums, int target) {int result = 0;if(nums==null || nums.length == 0){return result;}Arrays.sort(nums);for(int i=0; i<nums.length-1; i++){int start= i+1;int end= nums.length-1;while(start < end){if(nums[i] + nums[start] + nums[end] < target ){                    int count = end-start;  //这边不能一个一个走,原因是只单向移动start,会漏掉end符合条件的情况result += count;start++;}else{end--;}            }}     return result;}
}

382.Triangle Count:点击打开链接

例如:[3,4,6,7],Output:3

思路:sort数组后,i从后向前遍历数组,遍历的值nums[i]作为第三条边a,而nums[0]和nums[i-1]作为另两边b,c

因此如果满足b+c>a,就是一个三角形。

同时要注意,如果此时的b+c>a,得知(b后面的数)+c>a一定成立,所以直接加上这一段的有效三角形个数,然后end--;

如果b+c<a,就start++;

注意:此题的遍历方向

public class Solution {/*** @param S: A list of integers* @return: An integer*/public int triangleCount(int S[]) {if(S==null || S.length<3){return 0;}Arrays.sort(S);int count=0;for(int i=S.length-1;i>0;i--){            //数组从后往前倒着遍历int start=0;int end=i-1;while(start<end){if(S[start]+S[end]>S[i]){count+=end-start;end--;}else{start++;}}}return count;}
}

533.Two Sum-Closet to target: 点击打开链接

思路:还是 Two Sum双指针法,只是每次都要记录target与当前nums[start]+nums[end]的差值,并更新成最小的closet值,也就是最closet的。

public class Solution {/*** @param nums an integer array* @param target an integer* @return the difference between the sum and the target*/public int twoSumClosest(int[] nums, int target) {if(nums==null || nums.length<0){return 0;}Arrays.sort(nums);int start=0,end=nums.length-1;int closet=Integer.MAX_VALUE;while(start<end){if(nums[start]+nums[end]==target){                           //如果nums[]+nums[]==targetcloset=0;                                                //此时就是最理想的情况,要returnreturn closet;}else if(nums[start]+nums[end]<target){closet=Math.min(closet,target-nums[start]-nums[end]);start++;}else{closet=Math.min(closet,nums[start]+nums[end]-target);end--;}}return closet;}
}
public class Solution {/*** @param nums an integer array* @param target an integer* @return the difference between the sum and the target*/public int twoSumClosest(int[] nums, int target) {                 //或者用和3Sum Closet通用方法if(nums==null || nums.length<0){return 0;}Arrays.sort(nums);int start=0,end=nums.length-1;int closet=Integer.MAX_VALUE;while(start<end){int diff=nums[start]+nums[end]-target;if(Math.abs(diff)<closet){closet=Math.abs(diff);}if(diff==0){closet=0;return closet;}else if(diff<0){start++;}else{end--;}}return closet;}
}

59.3Sum Closet:点击打开链接

public class Solution {/*** @param numbers: Give an array numbers of n integer* @param target : An integer* @return : return the sum of the three integers, the sum closest target.*/public int threeSumClosest(int[] numbers, int target) {if(numbers==null || numbers.length<3){return 0;}Arrays.sort(numbers);int sum=0;int closet=Integer.MAX_VALUE;for(int i=0;i<numbers.length;i++){int start=i+1;int end=numbers.length-1;while(start<end){int diff=numbers[start]+numbers[end]+numbers[i]-target;  //先记录当前要用的三个数与target的差值if(Math.abs(diff)<closet){                               //每次都要比较当前绝对差值与closet的大小closet=Math.abs(diff);                               //更新closet值sum=numbers[start]+numbers[end]+numbers[i];          //并记录当前最小closet情况下的的sum}if(diff==0){                                             //差值为0就是最理想情况,此时要return closetreturn sum;}else if(diff>0){end--;}else{start++;}}}return sum;}
}

58.4Sum:点击打开链接

思路:和3Sum想法一样,不同点在于循环遍历两个数,另外两个数一个是start,一个是end

注意:题目要求输出list里不能包括重复的小list,因此循环遍历的两个数分别要检查是不是和后面的数相等

public class Solution {/*** @param numbers : Give an array numbersbers of n integer* @param target : you need to find four elements that's sum of target* @return : Find all unique quadruplets in the array which gives the sum of*           zero.*/public ArrayList<ArrayList<Integer>> fourSum(int[] numbers, int target) {ArrayList<ArrayList<Integer>> result=new ArrayList<>();if(numbers==null || numbers.length<4){return result;}Arrays.sort(numbers);for(int i=0;i<numbers.length-1;i++){                        if(i>0 && numbers[i]==numbers[i-1]){continue;}for(int j=i+1;j<numbers.length;j++){if(j!=i+1 && numbers[j]==numbers[j-1]){continue;}int start=j+1;int end=numbers.length-1;while(start<end){int sum=numbers[i]+numbers[j]+numbers[start]+numbers[end];if(sum>target){end--;}else if(sum<target){start++;}else{ArrayList<Integer>  list=new ArrayList<>();list.add(numbers[i]);list.add(numbers[j]);list.add(numbers[start]);list.add(numbers[end]);result.add(list);start++;end--;while(start<end && numbers[start]==numbers[start-1]){start++;}while(start<end && numbers[end]==numbers[end+1]){end--;}}}}}return result;}
}

31. Partition Array:点击打开链接

例如:[3,2,2,1],k=2,Output:1

思路:“两大阵营”

根据题意分阵营,左边都是小于k的数,右边都是大于k的数

相向双指针遍历数组,如果左边遍历到的数小于k就left++,如果右边遍历到的数大于k就right--

如果不属于我方阵营就和一个不属于对方阵营的数交换位置

注意: 1.本题最后return the partitioning index,eg:the first index i nums[i] =k,因为每次left++可以保证return left的值就是题目所要求。

2.题目还要求如果所以元素都比k小,就要返回数组的长度,例如:[1,1,1,1],k=2,Output:4

这种情况就是一直left++,当left=3时,仍然满足while(left<=right && nums[left]<k),还会再left++一次,此时返回left=4

public class Solution {/** *@param nums: The integer array you should partition*@param k: As description*return: The index after partition*/public int partitionArray(int[] nums, int k) {if(nums==null || nums.length==0){return 0;}int left=0;int right=nums.length-1;while(left<=right){while(left<=right && nums[left]<k){left++;}while(left<=right && nums[right]>=k){right--;}if(left<=right){int temp=nums[left];nums[left]=nums[right];nums[right]=temp;left++;right--;}}return left;}
}

373.Partition Array by Odd and Even:点击打开链接

public class Solution {/*** @param nums: an array of integers* @return: nothing*/public void partitionArray(int[] nums) {if(nums==null || nums.length==0){return;}int left=0;int right=nums.length-1;while(left<=right){                             //根据题意分两大阵营while(left<=right && nums[left]%2==1){      //奇数阵营left++;}while(left<=right && nums[right]%2==0){     //偶数阵营right--;}if(left<=right){int temp=nums[left];nums[left]=nums[right];nums[right]=temp;left++;right--;}}}
}

49. Sort Letters by Case:点击打开链接

public class Solution {/** *@param chars: The letter array you should sort by Case*@return: void*/public void sortLetters(char[] chars) {if(chars==null || chars.length==0){return;}int left=0;int right=chars.length-1;while(left<=right){                                         while(left<=right && chars[left]>='a' && chars[left]<='z'){       //小写字母阵营left++;}while(left<=right && chars[right]>='A' && chars[right]<='Z'){     //大写字母阵营right--;}if(left<=right){char temp=chars[left];chars[left]=chars[right];chars[right]=temp;left++;right--;}}}
}

144.Interleaving Positive and Negtive:点击打开链接

思路:与上面的两大阵营稍有不同,这题是用同向双指针,因为是正负数间隔,所以哪个符合条件哪个指针+2

但是题目没有说明原数组正,负整数的个数,因此要先判断正负数的个数情况,哪个多哪个就作为index=0

class Solution {/*** @param A: An integer array.* @return: void*/public void rerange(int[] A) {int posNum = 0, negNum = 0;  for (int i = 0; i < A.length; i++) {  if (A[i] > 0) {  posNum++;  } else {  negNum++;  }  }  int posIndex = 1, negIndex = 0;  if (posNum > negNum) {  posIndex = 0;  negIndex = 1;  }  while (negIndex < A.length && posIndex < A.length) {  while (negIndex < A.length && A[negIndex] < 0) {  negIndex += 2;  }  while (posIndex < A.length && A[posIndex] > 0) {  posIndex += 2;  }  if (posIndex < A.length && negIndex < A.length) {  int tmp = A[posIndex];  A[posIndex] = A[negIndex];  A[negIndex] = tmp;  posIndex += 2;  negIndex += 2;  }  }  }
}

148.Sort Colors:点击打开链接

3-way-partition问题

思路:1.由i遍历数组,leftPointer一直指向左边部分后一个数,rightPointer指向右边部分前一个数

2.如果当前nums[i]属于左边部分,nums[leftPointer]和nums[i]交换位置,使得leftPointer真正指向一个属于左边部分的数

然后leftPointer++,i++同步跟上

3.如果当前nums[i]属于中间部分,i++表示跳过,因为中间部分的元素就要留在中间

4.如果当前nums[i]属于右边部分,nums[rightPointer]和nums[i]交换位置,使得rightPointer真正指向一个属于右边部分的数

然后rightPointer--,此时,i不能同步++向后移,因为不知道被换的nums[rightPointer]是不是也属于右边部分,

所以还要从这个i位置开始看nums[i]属于哪个部分

注意:多跑几个例子就可以知道,i会比leftPointer走的快,所以即使交换后leftPointer指向的是左边阵营结束元素的下一个元素,也是i走过的元素,因此是1

rightPointer指向的是右边阵营结束元素的下一个元素,但是方rightPointer的走向是向左的

class Solution {/*** @param nums: A list of integer which is 0, 1 or 2 * @return: nothing*/public void sortColors(int[] nums) {if(nums==null || nums.length==0){return;}int leftPointer=0;                                     int rightPointer=nums.length-1;                        int i=0;                                               while(i<=rightPointer){                                if(nums[i]==0){swap(nums,i,leftPointer);                      //是0就被交换到1阵营leftPointer++;i++;}else if(nums[i]==1){                            i++;                                           //是1就跳过}else{swap(nums,i,rightPointer);                     //是2就被交换到当前2阵营rightPointer--;}}}private void swap(int[] nums,int i,int j){int temp=nums[i];nums[i]=nums[j];nums[j]=temp;}
}

625.Partition Array II:点击打开链接

public class Solution {/*** @param nums an integer array* @param low an integer* @param high an integer* @return nothing*/public void partition2(int[] nums, int low, int high) {if(nums==null || nums.length==0){return;}int i=0;int leftPointer=0;int rightPointer=nums.length-1;while(i<=rightPointer){if(nums[i]<low){swap(nums,i,leftPointer);leftPointer++;i++;}else if(nums[i]>=low && nums[i]<=high){i++;}else if(nums[i]>high){swap(nums,i,rightPointer);rightPointer--;}}}private void swap(int[] nums,int i,int j){int temp=nums[i];nums[i]=nums[j];nums[j]=temp;}
}

143.Sort Colors II:点击打开链接

彩虹排序问题 : O(nlogk)

思路:先分成两分,再递归分

例如:[3,2,2,1,4],k=4

先分成colorMid=(colorFrom+colorTo)/2=(1+4/)2=2,所以开始的两分是[2,2,1,3,4],再递归分每一分[2,2,1]和[3,4]

也就是两分先有个大致顺序,再不断递归局部的顺序,直到整体完全有序。

注意:前面两个return;

class Solution {/*** @param colors: A list of integer* @param k: An integer* @return: nothing*/public void sortColors2(int[] colors, int k) {if(colors==null || colors.length<k-1){return;}rainbowSort(colors,1,k,0,colors.length-1);}private void rainbowSort(int[] nums,int colorFrom,int colorTo,int left,int right){if(colorFrom==colorTo){return;}if(left>right){return;}int colorMid=(colorFrom+colorTo)/2;int l=left,r=right;while(l<=r){while(l<=r && nums[l]<=colorMid){l++;}while(l<=r && nums[r]>colorMid){r--;}if(l<=r){int temp=nums[l];nums[l]=nums[r];nums[r]=temp;l++;r--;}}rainbowSort(nums,colorFrom,colorMid,left,r);                   //while(l<=r)是循环条件,所以跳出了l>r是跳出条件rainbowSort(nums,colorMid+1,colorTo,l,right);                  //所以下一次递归的时候一定是l>r,r在前面}
}

[Algorithm]九章七:Two Pointer相关推荐

  1. [Algorithm]九章九之一:Matrix DP

    109. Triangle:点击打开链接 方法一:自底向上 例如:从6开始,依赖于4和1中小者,再加上本身 注意:这种三角形第n行的长度是n+1,一共有n-1行,第0行的长度为1, Time:O(n^ ...

  2. SQL基础教程MICK版 ···第七、八、九章总结

    SQL基础教程MICK版 ···第七.八.九章总结 表的联结 -- 内联结.外联结 表的合并--- UNION (其他操作对MYSQL不适用.没有看) 关于ROLLUP---显示小计和总计 驱动的概念 ...

  3. ★【世龙最爱之作】☆【丑丫头变身美女校花,不恋情的人懊恼,可是有了爱情之后更烦恼】第七十九章★

    丑丫头变身美女校花第七十九章 全部烧烤大餐,终极仍是以快活满意的主旋律,在一个半小时之后完善的停止了.合法大家都整理筹备散场的时候. 沈芳突然道:"要不,大家去唱歌吧?" 吴以默立 ...

  4. 鸟哥的Linux私房菜(服务器)- 第十九章、主机名控制者: DNS 服务器

    第十九章.主机名控制者: DNS 服务器 最近更新日期:2011/08/05 我们都知道,在『记忆』的角色上,人脑总是不如计算机的,而人们对文字的印象又比数字高.因此,想要使用纯粹的 TCP/IP 来 ...

  5. 第十九章、主機名稱控制者: DNS 伺服器

    转自:http://linux.vbird.org/linux_server/0350dns.php 第十九章.主機名稱控制者: DNS 伺服器 最近更新日期:2011/08/05 我們都知道,在『記 ...

  6. 中科大“九章”历史性突破,但实现真正的量子霸权还有多远?

    作者 | 马超 出品 | AI科技大本营 头图 | CSDN下载自视觉中国 10月中旬,政府高层强调要充分认识推动量子科技发展的重要性和紧迫性,加强量子科技发展战略谋划和系统布局,把握大趋势,下好先手 ...

  7. 分治习题--九章算法培训课第三章笔记

    1.Maximum Depth of Binary Tree 这是道简单的分治习题了 分: 左子树最大深度 右子树最大深度 治: 最大深度等于max(左子树,右子树)+1 public class S ...

  8. 最长回文子串动态规划_九章算法 | 微软面试题:最长回文子串

    给出一个字符串(假设长度最长为1000),求出它的最长回文子串,你可以假定只有一个满足条件的最长回文串. 在线评测地址:LintCode 领扣 样例 1: 输入:"abcdzdcab&quo ...

  9. 鸟哥的Linux私房菜(基础篇)- 第十九章、认识与分析登录文件

    第十九章.认识与分析登录文件 最近升级日期:2009/09/14 当你的 Linux 系统出现不明原因的问题时,很多人都告诉你,你要查阅一下登录文件才能够知道系统出了什么问题了,所以说,了解登录文件是 ...

最新文章

  1. RK3399 Ubuntu修改任务栏为自动隐藏和修改桌面背景
  2. DWM1000 长距离模块讨论
  3. 注意,ruby循环体定义的变量在结束时后,变量还存在
  4. 函数--函数的快速体验
  5. Android Studio更新成2.3以后Gradle大坑拯救,gradle安装异常解决办法
  6. 小汤学编程之JavaEE学习day05——会话管理、文件上传与下载、Ajax
  7. 【FlexSim2019】自学笔记:一个实例看何为A连接?何为S连接?其意义的深入探讨
  8. MD1——2 Corner
  9. 5.3 Zend_Log_Filter
  10. RTR/SLA 在多ISP环境下下的应用--已经更新,切换后线路恢复时,已能自动恢复
  11. Centos7 安装字体库中文字体
  12. winform textbox文本框根据内容自动调整高度
  13. HFSS - 同轴馈电矩形微带天线设计与仿真
  14. 网络工程师职场进化手册
  15. HTML——HTML中的特殊符号
  16. kali翻译插件_Kali2.0上的一款翻译神器【GoldenDict神器介绍】
  17. 详解sigmoid与softmax, 多分类及多标签分类
  18. Windows 平台下局域网劫持测试工具 – EvilFoca
  19. 6款真正好用的播放器推荐
  20. 用MATLAB绘制国债NSS模型,Matlab在数字信号处理中的运用.ppt

热门文章

  1. SpringBoot 项目中 YML 配置文件的使用
  2. 公司网站如何让用户使用QQ第三方登录
  3. KubeCon + 欧洲云原生大会 2022,看看云原生Wasm日的演讲
  4. 计算机打印机提示无法打印,电脑打印提示由于打印机的当前设置有问题,Windows无法打印怎么解决...
  5. 安全,恐惧,社会生活,含蓄,贱化,衰老
  6. 卡尔曼滤波器公式推导
  7. SolarWinds安装、配置、使用手册
  8. 微信小程序图片无缝衔接(微信小程序)
  9. [cognexVisionPro]错误:Vpp_1.vpp包含Cognex.visionPro.ToolBlock.CogToolBloc而不是CogJob
  10. iphone4越狱后找不到可以安装的openssh