乱序版 ● 剑指offer每日算法题打卡题解—— 双指针(题号21,57,58)

Posted 寂静花开

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了乱序版 ● 剑指offer每日算法题打卡题解—— 双指针(题号21,57,58)相关的知识,希望对你有一定的参考价值。

打卡day9

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

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

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

提示:
0 <= nums.length <= 50000
1 <= nums[i] <= 10000

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof

解题思路:
定义两个指针,一个 left 正序寻找偶数,一个 right 倒序寻找奇数。left找的偶数和right找的奇数位置交换。

java代码:

class Solution {
    public int[] exchange(int[] nums) {
    	//定义两个指针
        int left = 0, right = nums.length - 1, tmp;
        while(left < right) {//两指针重合时跳出循环
            while(left < right && (nums[left] % 2) != 0) {
            	left++;//找到偶数跳出
            }
            while(left < right && (nums[right] % 2 ) == 0) {
            	right--;//找到奇数跳出
            }
            //交换
            tmp = nums[left];
            nums[left] = nums[right];
            nums[right] = tmp;
        }
        return nums;

    }
}

第二题:剑指 Offer 57. 和为s的两个数字

输入一个递增排序的数组和一个数字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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/he-wei-sde-liang-ge-shu-zi-lcof

解题思路:
要注意,数组是递增排序的,依旧是定义左右指针。

java代码:

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) {//如果这个和小于目标值,左指针往右移
            	left++;
            }
            else if(sum > target) {//如果这个和大于目标值,右指针往左移
            	right--;
            }
            else {//和目标值相等的话,返回左右指针
            	return new int[] { nums[left], nums[right] };
            }
        }
        return new int[0];//都不等,返回空数组
    }
}

第三题:剑指 Offer 58 - I. 翻转单词顺序

输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"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”
解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/fan-zhuan-dan-ci-shun-xu-lcof

解题思路:
倒序遍历字符串s,记录单词左右索引边界left、right,将得到的单词放到列表里
最后将列表重新拼接为字符串。

java代码:

class Solution {
    public String reverseWords(String s) {
        s = s.trim(); // 删除两端的空格
        int right = s.length() - 1, left = right;
        StringBuilder res = new StringBuilder();//定义可变字符串
        while(left >= 0) {
            while(left >= 0 && s.charAt(left) != ' ') {// 搜索单词边界
            	left--; 
            }
            res.append(s.substring(left + 1, right + 1) + " "); // 添加单词
            while(left >= 0 && s.charAt(left) == ' ') {
                 left--; // 跳过单词间空格
             }
            right = left; // 指向下个单词的末尾字符
        }
        return res.toString().trim(); // 转化为字符串并返回,且去除两端多余空格
    }
}

以上是关于乱序版 ● 剑指offer每日算法题打卡题解—— 双指针(题号21,57,58)的主要内容,如果未能解决你的问题,请参考以下文章

乱序版 ● 剑指offer每日算法题打卡题解—— 查找算法 (题号3,4,11,53)

乱序版 ● 剑指offer每日算法题打卡题解——分治算法(题号17,14)

乱序版 ● 剑指offer每日算法题打卡题解——数学 (题号39,66)

乱序版 ● 剑指offer每日算法题打卡题解——动态规划(题号19,49,60)

乱序版 ● 剑指offer每日算法题打卡题解——动态规划 (题号10,63)

乱序版 ● 剑指offer每日算法题打卡题解——栈与队列(题号59)