今天的题目仍然与数组有关,一般暴力解法的时间复杂度为O(n^2),采用双指针法,时间复杂度为O(n)。
1.删除有序数组中的重复项(力扣26)
从头开始遍历,遇到相同元素slowindex不变,遇到不同时记录fastindex的元素
public int removeDuplicates(int[] nums) { int slowindex = 0; for (int fastindex = 0; fastindex < nums.length; fastindex++) { if(fastindex == nums.length-1) { nums[slowindex++] = nums[fastindex]; break; } if(nums[fastindex] != nums[fastindex+1]) { nums[slowindex++] = nums[fastindex]; } } return slowindex; }
2.移动零(力扣283)
同上题,在上题的基础上将零元素全部放到数组最后
public void moveZeroes(int[] nums) { int lowindex = 0; for (int fastindex = 0; fastindex < nums.length; fastindex++) { if(nums[fastindex] != 0) { nums[lowindex++] = nums[fastindex]; } } for (int i = lowindex; i < nums.length; i++) { nums[i] = 0; } }
3.比较含退格的字符串(力扣844)
本题选用双指针法来将需要退格的字符覆盖
public boolean backspaceCompare(String s, String t) { char[] charS = s.toCharArray(); char[] charT = t.toCharArray(); int lowindex = 0; for (int fastindex = 0; fastindex < charS.length; fastindex++) { if(charS[fastindex] != '#') charS[lowindex++] = charS[fastindex]; else if(lowindex>0) lowindex--; } String s1 = new String(charS,0,lowindex); lowindex = 0; for (int fastindex = 0; fastindex < charT.length; fastindex++) { if(charT[fastindex] != '#') charT[lowindex++] = charT[fastindex]; else if(lowindex>0) lowindex--; } String s2 = new String(charT,0,lowindex); return s1.equals(s2); }
4.有序数组的平方(力扣977)
本题难度在于如何用时间复杂度为O(n)实现,从两头开始将平方值大的数放入新的数组。指针碰撞时,结束。
public int[] sortedSquares(int[] nums) { // 时间复杂度为o(nlogn) // for (int i = 0; i < nums.length; i++) { // nums[i] = nums[i]*nums[i]; // } // Arrays.sort(nums); // return nums; //时间复杂度为O(n), int[] res = new int[nums.length]; int lowindex = 0; int fastindex = nums.length-1; int pos = nums.length-1; while (lowindex!=fastindex){ if(nums[lowindex]*nums[lowindex]>=nums[fastindex]*nums[fastindex]) { res[pos--] = nums[lowindex]*nums[lowindex]; lowindex++; } else { res[pos--] = nums[fastindex] * nums[fastindex]; fastindex--; } } res[pos] = nums[lowindex]*nums[lowindex]; return res; }
5.长度最小的子数组
使用滑动窗口来改变满足和大于等于给定值的子数组大小,如果窗口太大,需要从右边开始缩小。
public int minSubArrayLen(int target, int[] nums) { int slowindex = 0; int result = 100000; int subLength = 0; int sum = 0; for (int fastindex = 0;fastindex<nums.length;fastindex++){ sum = sum + nums[fastindex]; while (sum >= target){ subLength = fastindex - slowindex + 1; if (result > subLength) result = subLength; sum = sum - nums[slowindex++]; } } if(result == 100000) return 0; else return result; }
*6.水果成篮问题(力扣904)
这道题一个关键点是用数组表示各种水果(数字)的数量,然后使用滑动窗口从左往右改变窗口。看了解析才明白,需要复习。
public int totalFruit(int[] fruits) { int left = 0; int right = 0; int res = 2; if(fruits.length == 1 || fruits.length == 2) return fruits.length; int[] arr = new int[fruits.length];//存放水果种类 int count = 0; while (right<fruits.length){ if(arr[fruits[right]] == 0) count++; arr[fruits[right]]++; right++; while (count>2){ arr[fruits[left]]--; if(arr[fruits[left]] == 0) count--; left++; } if(right - left > res) res = right - left; } return res; }