白银-双指针思想专题

本文介绍了几种针对数组的操作方法,包括使用快慢双指针删除特定元素、去除有序数组重复项、按奇偶性排序数组、实现数组轮转以及替换字符串中的空格。这些算法涉及到了基本的数据结构操作和效率优化策略。
摘要由CSDN通过智能技术生成

1.删除元素专题

1.1.移除元素

image-20230724181454047

快慢双指针:fast遇到不等时,将值赋给slow并后移slow。

public int removeElement(int[] nums, int val) {
        int slow = 0;
        int fast = 0;
        for(int i = 0;i < nums.length;i++){
            if(nums[i] != val){
                nums[slow++] = nums[fast];
            }
            fast++;
        }
        return slow;
    }
1.2.删除有序数组中的重复项
public int removeDuplicates(int[] nums) {
        int slow = 1;
        for(int fast = 0;fast < nums.length;fast++){
            if(nums[slow -1] != nums[fast]){
                nums[slow++] = nums[fast];
            }
        }
        return slow;
    }

2.元素奇偶移动

记数组 nums 的长度为 n。先从 nums 左侧开始遍历,如果遇到的是偶数,就表示这个元素已经排好序了,继续从左往右遍历,直到遇到一个奇数。然后从 nums右侧开始遍历,如果遇到的是奇数,就表示这个元素已经排好序了,继续从右往左遍历,直到遇到一个偶数。交换这个奇数和偶数的位置,并且重复两边的遍历,直到在中间相遇,nums 排序完毕。

public int[] sortArrayByParity(int[] nums) {
        int left = 0;
        int right = nums.length - 1;
        while(left < right){
            while( left < right && nums[left] % 2 == 0) left++;
            while(left < right && nums[right] % 2 != 0) right--;
            if(left < right){
                int temp = nums[left];
                nums[left] = nums[right];
                nums[right] = temp;
            }
            
        }
        return nums;
    }

3.轮转数组

image-20230725105902150

观察输入和输出,发现只需要进行两次反转即可。

注意:需要对k进行取余,判断k的合法性

public void rotate(int[] nums, int k) {
        k%=nums.length;
        //两次反转
        // 整体反转
        revese(nums,0,nums.length-1);
        // 前半部分
        revese(nums,0,k-1);
        // 后半部分
        revese(nums,k,nums.length-1);
    }
    public void revese(int[] nums,int left,int right){
        while(left < right){
            int temp = nums[left];
            nums[left] = nums[right];
            nums[right] = temp;
            left++;
            right--;
        }
    }

4.数组区间专题

image-20230725122246303

快慢指针,当到达数组边界或者不满足连续时,拼接成字符串加入集合。这里要注意对最后一个元素的特殊处理

public List<String> summaryRanges(int[] nums) {
        List<String> list = new ArrayList<>();
        int slow = 0;
        for(int fast =0;fast < nums.length;fast++){
            // 到达边界或者不满足连续
            if(fast+1 == nums.length || nums[fast]+1 != nums[fast+1]){
                StringBuilder sb = new StringBuilder();
                sb.append(nums[slow]);
                // 处理最后一位
                if(slow != fast){
                    sb.append("->").append(nums[fast]);
                }
                list.add(sb.toString());
                // 移动slow
                slow = fast+1;
            }
        }
        return list;
    }

5.字符串替换空格问题

image-20230725122908444

5.1.直接暴力求解
public String replaceSpace(String s) {
        StringBuilder sb = new StringBuilder();
        for(int i =0;i < s.length();i++){
            char c = s.charAt(i);
            if(c == ' '){
                sb.append("%20");
            }
            else{
                sb.append(c);
            }
        
        }
        return sb.toString();
    }
5.2.快慢双指针原地修改

关键点:

  1. 求出替换后字符串长度
  2. 从后向前填充(快慢指针)
 public static String replaceSpace2(StringBuffer str) {
        if (str == null)
            return null;
        int numOfblank = 0;//空格数量
        int len = str.length();
        for (int i = 0; i < len; i++) {  //计算空格数量
            if (str.charAt(i) == ' ')
                numOfblank++;
        }
        str.setLength(len + 2 * numOfblank); //设置长度
        int fast = len - 1;  //两个指针
        int slow = (len + 2 * numOfblank) - 1;

        while (fast >= 0 && slow > fast) {
            char c = str.charAt(fast);
            if (c == ' ') {
                fast--;
                str.setCharAt(slow--, '0');
                str.setCharAt(slow--, '2');
                str.setCharAt(slow--, '%');
            } else {
                str.setCharAt(slow, c);
                fast--;
                slow--;
            }
        }
        return str.toString();
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值