【剑指 Offer 学习计划】第十三天 双指针

第十三天 双指针 (简单)

剑指 Offer 21. 调整数组顺序使奇数位于偶数前面

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof

题目

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数在数组的前半部分,所有偶数在数组的后半部分。

示例:

输入:nums = [1,2,3,4]
输出:[1,3,2,4] 
注:[3,1,2,4] 也是正确的答案之一。

提示:

  • 0 <= nums.length <= 50000
  • 0 <= nums[i] <= 10000

解题思路:

双指针。

左指针找偶数,右指针找奇数,两边交换。

直到指针左边都是奇数,指针右边都是偶数

代码

class Solution {
    
    
    public int[] exchange(int[] nums) {
    
    
        int left = 0, right = nums.length - 1;
        while(left < right) {
    
    
            while(left < right && (nums[left] & 1) != 0) {
    
    
                left ++;
            }
            while(left < right && (nums[right] & 1) == 0) {
    
    
                right --;
            }
            int temp = nums[left];
            nums[left] = nums[right];
            nums[right] = temp;
        }
        return nums;
    }
}

在这里插入图片描述

剑指 Offer 57. 和为s的两个数字

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/he-wei-sde-liang-ge-shu-zi-lcof

题目

输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。

示例 1:

输入:nums = [2,7,11,15], target = 9
输出:[2,7] 或者 [7,2]

示例 2:

输入:nums = [10,26,30,31,47,60], target = 40
输出:[10,30] 或者 [30,10]

限制:

  • 1 <= nums.length <= 10^5
  • 1 <= nums[i] <= 10^6

解题思路:

双指针。

题目有注明 :递增数组。

可以使用双指针左右夹击。

  • 若左右指针对应的索引的值的和等于 target,返回。
  • 若左右指针对应的索引的值的和大于 target,右指针的值太大了,right --。
  • 若左右指针对应的索引的值的和小于 target,左指针的值太小了,left --。

代码

class Solution {
    
    
    public int[] twoSum(int[] nums, int target) {
    
    
        int left = 0, right = nums.length - 1;
        while(left < right) {
    
    
            int sum = nums[left] + nums[right];
            if(sum == target) {
    
    
                return new int[]{
    
    nums[left] , nums[right]};
            }else if(sum > target) {
    
    
                right --;
            }else {
    
    
                left ++;
            }
        }
        return null;
    }
}

在这里插入图片描述

剑指 Offer 58 - I. 翻转单词顺序

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/fan-zhuan-dan-ci-shun-xu-lcof

题目

输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student. “,则输出"student. a am I”。

示例 1:

输入: "the sky is blue"
输出: "blue is sky the"

示例 2:

输入: "  hello world!  "
输出: "world! hello"
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。

示例 3:

输入: "a good   example"
输出: "example good a"
解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。

说明:

  • 无空格字符构成一个单词。
  • 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
  • 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。

解题思路:

双指针。

倒序遍历,左指针、右指针分别代表单词的左右下标。

  • 倒序遍历,直到指针指向的字符不为空(去除两个单词间有多余的空格),此为单词右下标
  • 继续遍历,直到指针指向的字符为空,此为单词左下标
  • 将双指针左右夹击的单词字符串加入到 StringBuilder 中
  • 最后返回结果,记得去除最后的空格。

代码

class Solution {
    
    
    public String reverseWords(String s) {
    
    
        s = s.trim();
        StringBuilder sb = new StringBuilder(); // 保存结果
        int left = s.length() -1, right = left; // 单词左右
        while(left >= 0) {
    
    
            while(left >= 0 && s.charAt(left) == ' ') {
    
    
                left --;
            }
            right = left;
            while(left >= 0 && s.charAt(left) != ' ') {
    
    
                left --;
            }
            sb.append(s.substring(left + 1, right + 1)).append(" ");
        }
        return sb.toString().trim();
    }
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44695700/article/details/121432800