Cracking Coding Interview - 10.11 Peaks and Valleys

Peaks and Valleys: In an array of integers, a “peak” is an element which is greater than or equal to the adjacent integers and a “valley” is an element which is less than or equal to the adjacent integers. For example, in the array {5, 8, 6, 2, 3, 4, 6}, {8, 6} are peaks and {5, 2} are valleys. Given an array of integers, sort the array into an alternating sequence of peaks and valleys.

EXAMPLE

1
2
Input:  {5, 3, 1, 2, 3}
Output: {5, 1, 3, 2, 3}

Hints: #196, #219, #231, #253, #277, #292, #316

解法1

什么是Peak? >= 左右两边的数字就是Peak。

什么是Valley?<= 左右两边的数字就是Valley。

给你一个数组,对它排序,使得它的Peak和Valley交替。换句话说就是{大、小、大、小}这样。

现在看一个已经排序好的数组:

1
a1, a2, a3, a4, a5

那么我们可以从左右两边向中间取元素,交替放置:

1
2
a5, a1
a5, a1, a4, a2, a3

代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
public int[] peakValleys(int[] array) {
  int[] result = new int[array.length];
  Arrays.sort(array);
  int head = 0;
  int tail = array.length - 1;
  int i = 0;
  while (head < tail) {
    result[i] = array[tail];
    tail--;
    i++;
    result[i] = array[head];
    head++;
    i++;
  }
  if (head == tail) {
    result[i] = array[head];
  }
  return result;
}

解法2

有没有办法不对数组做排序来弄?可以弄一个指针从index 1开始遍历,在两个检查模式中切换:

  1. 当前元素比前一个元素小
  2. 当前元素比前一个元素大

如果检查结果为false,那么就将当前元素和前一个元素交换

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
mode_lt = check(a[i] < a[i - 1]) == true
mode_gt = check(a[i] > a[i - 1]) == true

Round 1: mode_lt, check pass
   v
5, 3, 1, 2, 3

Round 2: mode_gt, check fail, swap
      v
5, 3, 1, 2, 3 -> 5, 1, 3, 2, 3

Round 3: mode_lt, check pass
         v
5, 1, 3, 2, 3

Round 4: mode_gt, check pass
            v
5, 1, 3, 2, 3

代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public void peakValley(int[] array) {
  if (array.length <= 1) {
    return;
  }
  int mode = MODE_LT;
  for (int i = 1; i < array.length; i++) {
    if (mode == MODE_LT) {
      if (!(array[i] < array[i - 1])) {
        swap(array, i, i - 1);
      }
      mode = MODE_GT;
    } else {
      if (!(array[i] > array[i - 1])) {
        swap(array, i, i - 1);
      }
      mode = MODE_LT;
    }
  }
}

private void swap(int[array], int i, int j) {
  int tmp = array[i];
  array[i] = array[j];
  array[j] = tmp;
}

版权

评论