Files
LeetCode-Book/leetbook_ioa/docs/LCR 139. 训练计划 I.md
krahets de1a505d63 Add documents of leetbook IOA and
selected coding interview.
2023-10-10 20:22:09 +08:00

4.0 KiB
Executable File
Raw Permalink Blame History

解题思路:

考虑定义双指针 i , j 分列数组左右两端,循环执行:

  1. 指针 i 从左向右寻找偶数;
  2. 指针 j 从右向左寻找奇数;
  3. 将 偶数 actions[i] 和 奇数 actions[j] 交换。

可始终保证: 指针 i 左边都是奇数,指针 j 右边都是偶数 。

下图中的 nums 对应本题的 actions

Picture1.png{:align=center width=450}

算法流程:

  1. 初始化: i , j 双指针,分别指向数组 actions 左右两端;
  2. 循环交换:i = j 时跳出;
    1. 指针 i 遇到奇数则执行 i = i + 1 跳过,直到找到偶数;
    2. 指针 j 遇到偶数则执行 j = j - 1 跳过,直到找到奇数;
    3. 交换 actions[i]actions[j] 值;
  3. 返回值: 返回已修改的 actions 数组。

<Picture2.png,Picture3.png,Picture4.png,Picture5.png,Picture6.png,Picture7.png,Picture8.png,Picture9.png,Picture10.png,Picture11.png,Picture12.png,Picture13.png,Picture14.png>

代码:

x \& 1 位运算 等价于 x \mod 2 取余运算,即皆可用于判断数字奇偶性。

class Solution:
    def trainingPlan(self, actions: List[int]) -> List[int]:
        i, j = 0, len(actions) - 1
        while i < j:
            while i < j and actions[i] & 1 == 1: i += 1
            while i < j and actions[j] & 1 == 0: j -= 1
            actions[i], actions[j] = actions[j], actions[i]
        return actions
class Solution {
    public int[] trainingPlan(int[] actions) {
        int i = 0, j = actions.length - 1, tmp;
        while(i < j) {
            while(i < j && (actions[i] & 1) == 1) i++;
            while(i < j && (actions[j] & 1) == 0) j--;
            tmp = actions[i];
            actions[i] = actions[j];
            actions[j] = tmp;
        }
        return actions;
    }
}
class Solution {
public:
    vector<int> trainingPlan(vector<int>& actions)
    {
        int i = 0, j = actions.size() - 1;
        while (i < j)
        {
            while(i < j && (actions[i] & 1) == 1) i++;
            while(i < j && (actions[j] & 1) == 0) j--;
            swap(actions[i], actions[j]);
        }
        return actions;
    }
};

复杂度分析:

  • 时间复杂度 O(N) N 为数组 actions 长度,双指针 i, j 共同遍历整个数组。
  • 空间复杂度 O(1) 双指针 i, j 使用常数大小的额外空间。