例如:[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
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
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
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
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;
}
}
思路:当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;
}
}
例如: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
题意:这题就是要恢复成有序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 nums) {
if(nums==null || nums.size()==0){
return;
}
int k=0;
for(int i=0;inums.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 nums,int start,int end){
while(start
下面就是经典题型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 map=new HashMap<>(); //例如:[2,7,11,15],target=9
for(int i=0;i
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;
}
}
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(starttarget){
end--;
}else{
result[0]=start+1; //注意好题目要求是non zero-based,还是zero-based
result[1]=end+1;
return result;
}
}
return null;
}
}
public class TwoSum { //只能使用HashMap的
private List list=null;
private Map 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 here
if(!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;i1){
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);
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(starttarget){
end--;
}else{
start++;
}
}
return count;
}
}
例如:[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
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
例如:[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 map=new HashMap<>();
for(int i=0;i
例如:[-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> threeSum(int[] numbers) {
ArrayList> result=new ArrayList<>();
if(numbers==null || numbers.length<3){ //只要numbers.length<3就不符合题意了
return result;
}
Arrays.sort(numbers);
for(int i=0;i0 && 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> result){
while(start list=new ArrayList<>();
list.add(-target);
list.add(nums[start]);
list.add(nums[end]);
result.add(list);
start++;
end--;
while(start
例如:[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> threeSum(int[] numbers) { //方法二:直接看当前三个数的和是不是等于0
ArrayList> result=new ArrayList<>(); //个人感觉这个方法更直接,更容易弄懂
if(numbers==null || numbers.length<3){
return result;
}
Arrays.sort(numbers);
for(int i=0;i0 && numbers[i]==numbers[i-1]){ //如果i重复
continue; //跳出本次i,进入for循环里的下一个i
}
int start=i+1;
int end=numbers.length-1;
while(start list=new ArrayList<>();
list.add(numbers[i]);
list.add(numbers[start]);
list.add(numbers[end]);
result.add(list);
start++;
end--;
while(start
public int threeSumMulti(int[] A, int target) {
int mol = 1000000007; // 如果写成10^9+7的形式,就过不了,Bitwise Operators
Arrays.sort(A);
int res = 0;
Map 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
Given an array of n integers nums and a target, find the number of index triplets i, j, k
with 0 <= i < j < k < n
that 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]