|
1 | | -/** |
| 1 | +/* |
2 | 2 | * @param {number[]} nums
|
3 | | - * @return {void} Do not return anything, modify nums in-place instead. |
| 3 | + * @param {number} target |
| 4 | + * @return {number} |
4 | 5 | */
|
5 | | -function nextPermutation(nums) { |
6 | | - let i = nums.length - 2; // 向左遍历,i从倒数第二开始是为了nums[i+1]要存在 |
7 | | - while (i >= 0 && nums[i] >= nums[i + 1]) { |
8 | | - // 寻找第一个小于右邻居的数 |
9 | | - i--; |
10 | | - } |
| 6 | +var search = function (nums, target) { |
| 7 | + let left = 0; |
| 8 | + let right = nums.length - 1; |
11 | 9 |
|
12 | | - if (i >= 0) { |
13 | | - // 这个数在数组中存在,从它身后挑一个数,和它换 |
14 | | - let j = nums.length - 1; // 从最后一项,向左遍历 |
15 | | - while (j >= 0 && nums[j] <= nums[i]) { |
16 | | - // 寻找第一个大于 nums[i] 的数 |
17 | | - j--; |
| 10 | + while (left <= right) { |
| 11 | + let mid = Math.floor((left + right) / 2); |
| 12 | + if (nums[mid] === target) { |
| 13 | + return mid; |
18 | 14 | }
|
19 | | - [nums[i], nums[j]] = [nums[j], nums[i]]; // 两数交换,实现变大 |
20 | | - } |
21 | 15 |
|
22 | | - // 如果 i = -1,说明是递减排列,如 3 2 1,没有下一排列,直接翻转为最小排列:1 2 3 |
23 | | - let l = i + 1; |
24 | | - let r = nums.length - 1; |
25 | | - while (l < r) { |
26 | | - // i 右边的数进行翻转,使得变大的幅度小一些 |
27 | | - [nums[l], nums[r]] = [nums[r], nums[l]]; |
28 | | - l++; |
29 | | - r--; |
| 16 | + if (nums[mid] < nums[right]) { |
| 17 | + if (nums[mid] < target && target <= nums[right]) { |
| 18 | + left = mid + 1; |
| 19 | + } else { |
| 20 | + right = mid - 1; |
| 21 | + } |
| 22 | + } else { |
| 23 | + if (nums[mid] > target && target >= nums[left]) { |
| 24 | + right = mid - 1; |
| 25 | + } else { |
| 26 | + left = mid + 1; |
| 27 | + } |
| 28 | + } |
30 | 29 | }
|
31 | | -} |
| 30 | + |
| 31 | + return -1; |
| 32 | +}; |
| 33 | + |
| 34 | +const assert = require('assert').strict; |
| 35 | + |
| 36 | +assert.equal(search([4, 5, 6, 7, 0, 1, 2], 0), 4); |
0 commit comments