数组移除元素(快慢指针)

数组移除元素(快慢指针)

  • 1.移除元素
  • 2.删除排序数组中的重复项
  • 3.移动0
  • 4.比较含退格的字符串
  • 5.有序数组的平方

1.移除元素

移除元素

暴力解法

class Solution {
    /*
    * 暴力解法:使用两层for循环,第一层循环遍历数组,第二层循环更新数组
    */
    public int removeElement(int[] nums, int val) {
        int len = nums.length;
        for(int i =0;i<len;i++){
            if(nums[i]==val){
                for(int j =i+1;j<len;j++){
                    nums[i]=nums[j];//移除val,用i后面的元素覆盖
                }
                i--;//因为下表i以后的元素都向前移动一位,所以i也要向前移动一位
                len--;//此时数组的大小减一
            }

        }
        return len;
    }
}

快慢指针

class Solution {
    /*
    *   快慢指针:慢指针用来存储修改后的元素,快指针用来遍历
    */
    public int removeElement(int[] nums, int val) {
        int slowIndex = 0;//慢指针,用来存储修改后的元素

        for(int fastIndex = 0;fastIndex<nums.length;fastIndex++){//快指针用来遍历
            if(val!=nums[fastIndex]){//如果当前值不等于目标值,则存储在慢指针下;若相等,则继续遍历,不存储。。
                nums[slowIndex]=nums[fastIndex];
                slowIndex++;
            }
        }
        return slowIndex;
    }
}

2.删除排序数组中的重复项

快慢指针删除数组中的元素,注意slowIndex++;和return slowIndex+1;

删除有序数组中的重复项

class Solution {
    public int removeDuplicates(int[] nums) {
        int slowIndex = 0;//用于存储修改后的元素
        for(int fastIndex = 0;fastIndex<nums.length;fastIndex++){
            if(nums[slowIndex]!=nums[fastIndex]){//不相等时才存储数据,两数相等就跳过
                slowIndex++;//将数据存入慢指针下一位
                nums[slowIndex]=nums[fastIndex];
            }
        }
        return slowIndex+1;//slow从0开始,所以输出要加一
    }
}

3.移动0

快慢指针,本题与前两道题的区别是,我们需要移动完元素后,在末尾加0

移动0

class Solution {
    public void moveZeroes(int[] nums) {
        int slowIndex =0;//慢指针,用来存储
        
        for(int fastIndex =0;fastIndex<nums.length;fastIndex++){
            if(nums[fastIndex]!=0){
                nums[slowIndex]=nums[fastIndex];
                slowIndex++;
            }
        }
        //将后面的元素都变成0
        for(int j =slowIndex;j<nums.length;j++){
            nums[j]=0;
        }
    }
}

4.比较含退格的字符串

思路:我们选择从后向前遍历,定义sums和sumt来存储#的数量。
1.当前元素等于#时,sums/sumt加一
2.当前元素不等于#时,且sums/sumt大于0时,sums/sumt减一来抵消
3.当前元素不等于#时,且sums/sumt等于0时,退出当前循环
4.比较两个字符串是否相等

比较含退格的字符串

class Solution {
    public boolean backspaceCompare(String s, String t) {
        //双指针
        int i = s.length()-1;//从后向前遍历
        int j = t.length()-1;
        int sums = 0;//用来记录s中#的数量
        int sumt = 0;//用来记录t中#的数量

        while(i>=0||j>=0){
            //记录s中#的数量
            while(i>=0){
               if(s.charAt(i)=='#'){//当前元素等于#,记录下来
                   sums++;
                   i--;//可能为-1
               }
               else if(sums>0){//当前元素不等于#,且#的数量大于0
                    sums--;
                    i--;
               }else{//当前元素不等于#,且#的数量等于0,退出循环去比较
                   break;//退出当前循环
               }
            }
            //记录t中#的数量
            while(j>=0){
                if(t.charAt(j)=='#'){
                    sumt++;
                    j--;
                }
                else if(sumt>0){
                    sumt--;
                    j--;
                }else{
                    break;
                }
            }
            //比较除#外的元素是否相等
            if(i>=0&&j>=0){                    
                if(s.charAt(i)!=t.charAt(j))  return false;               
            }else{// (i >= 0 && j >= 0) 为 false 情况为
            // 1. i < 0 && j >= 0
            // 2. j < 0 && i >= 0
            // 3. i < 0 && j < 0
            // 其中,第 3 种情况为符合题意情况,因为这种情况下 s 和 t 都是 index = 0 的位置为 '#' 而这种情况下退格空字符即为空字符,也符合题意,应当返回 True。
            
            // 但是,情况 1 和 2 不符合题意,因为 s 和 t 其中一个是在 index >= 0 处找到了待比较字  符,另一个没有找到
            // 这种情况显然不符合题意,应当返回 False,下式便处理这种情况。
                    if(i>=0||j>=0){
                        return false;
                    }
                }
            i--;
            j--;
        }
        return true;
    }
}

5.有序数组的平方

各种排序的灵活使用

有序数组的平方

class Solution {
    public int[] sortedSquares(int[] nums) {
        for(int i =0;i<nums.length;i++){
            nums[i]=nums[i]*nums[i];
        }
        return sort(nums);
        
    }


    //冒泡排序
    private int[] sort(int[] nums){
        for(int i =nums.length-1;i>0;i--){
            for(int j =0;j<i;j++){//j+1,保证i后面必有一个
            if(nums[j]>nums[j+1])
                swap(nums,j,j+1);
            
            }
        }
        return nums;
        

    }
    //两数交换
    private void swap(int[] nums ,int i,int j){
        int temp = nums[i];
        nums[i]=nums[j];
        nums[j]=temp;
    }
}

平方在某种意义上也可以看作有序(首位两端)
注意要创建一个相同大小的数组进行数组的重新排序。(第一次忘记加了,然后就出错了)

class Solution {
    /*
    * 思路:有序数组的平方也可在某种意义上看作有序
    */
    public int[] sortedSquares(int[] nums) {
        int left = 0 ;
        int right = nums.length-1;
        int result[] = new int[right+1];//相同大小的新数组
        int ans = nums.length-1;//新数组的指针

        while(left<=right){
            if(nums[left]*nums[left]<=nums[right]*nums[right]){               
                result[ans--]=nums[right]*nums[right];
                right--;
            }else{
                
                result[ans--]=nums[left]*nums[left];
                left++;
            }
        }
        return result;
    }
}

你可能感兴趣的:(算法,leetcode,算法,数据结构)