1. 概述

给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

注意:

不能使用代码库中的排序函数来解决这道题。

示例:

输入: [2,0,2,1,1,0]

输出: [0,0,1,1,2,2]

2. 解题

  1. <?php
  2. class Solution
  3. {
  4. /**
  5. * @param Integer[] $nums
  6. * @return NULL
  7. */
  8. public function sortColors(&$nums)
  9. {
  10. for ($i = 1; $i < count($nums); $i++) {
  11. $j = $i;
  12. while ($j > 0) {
  13. if ($nums[$j] < $nums[$j - 1]) {
  14. $exchange = $nums[$j];
  15. $nums[$j] = $nums[$j - 1];
  16. $nums[$j - 1] = $exchange;
  17. }
  18. $j--;
  19. }
  20. }
  21. return;
  22. }
  23. /**
  24. * todo
  25. * @param Integer[] $nums
  26. * @return NULL
  27. */
  28. public function sortColors2(&$nums)
  29. {
  30. $white = -1;
  31. $left = -1;
  32. $right = count($nums) - 1;
  33. $min = $nums[0];
  34. for ($i = 1; $i <= $right; $i++) {
  35. ($nums[$i] < $min) && $min = $nums[$i];
  36. }
  37. // 遍历一次数组
  38. for ($i = 0; $i <= $right; $i++) {
  39. if ($left == -1 && $nums[$i] == $min) {
  40. $left = $i;
  41. }
  42. if ($nums[$i] == 0) {
  43. isset($nums[$left + 1]) && $this->swap($nums, $i, ++$left);
  44. } elseif ($nums[$i] == 2) {
  45. isset($nums[$right - 1]) && $this->swap($nums, $i, --$right);
  46. }
  47. }
  48. return;
  49. }
  50. private function swap(&$nums, $i, $j)
  51. {
  52. $tmp = $nums[$i];
  53. $nums[$i] = $nums[$j];
  54. $nums[$j] = $tmp;
  55. }
  56. }
  57. $nums = [2, 0, 2, 1, 1, 0, 0, 0, 0, 1, 2, 0, 2, 1, 0, 0, 2, 2, 2, 0, 0, 0, 1, 1, 2];
  58. // echo implode(',', $nums) . "\n";
  59. $cls = new Solution();
  60. // $cls->sortColors($nums);
  61. $cls->sortColors2($nums);
  62. echo implode(',', $nums) . "\n";