- 旋轉數組 給定一個數組,將數組中的元素向右移動 k 個位置,其中 k 是非負數。
示例1 輸入: [1,2,3,4,5,6,7] 和 k = 3
輸出: [5,6,7,1,2,3,4]
解釋:
向右旋轉 1 步: [7,1,2,3,4,5,6]
向右旋轉 2 步: [6,7,1,2,3,4,5]
向右旋轉 3 步: [5,6,7,1,2,3,4]
示例2 輸入: [-1,-100,3,99] 和 k = 2
輸出: [3,99,-1,-100]
解釋:
向右旋轉 1 步: [99,-1,-100,3]
向右旋轉 2 步: [3,99,-1,-100]
說明:
儘可能想出更多的解決方案,至少有三種不同的方法可以解決這個問題。
要求使用空間複雜度爲 O(1) 的 原地 算法。
方法一
public void rotate(int[] nums, int k) {
int j = 0;
while (j < k) {
int last = nums[nums.length - 1];
for (int i = nums.length - 1; i > 0; i--) {
nums[i] = nums[i - 1];
}
nums[0] = last;
j++;
}
}
方法二:
public void rotate(int[] nums, int k) {
for (int j = 0; j < k; j++) {
int last = nums[nums.length - 1];
for (int i = nums.length - 1; i > 0; i--) {
nums[i] = nums[i - 1];
}
nums[0] = last;
}
}
方法三
public void rotate(int[] nums, int k) {
int temp, previous;
for (int j = 0; j < k; j++) {
previous = nums[nums.length - 1];
for (int i = 0; i < nums.length; i ++) {
temp = nums[i];
nums[i] = previous;
previous = temp;
}
}
}
尋找旋轉排序數組中的最小值
方法一:暴力, 時間複雜度爲O(n)
public int findMin(int[] nums) {
int min = nums[nums.length - 1], temp, pre = nums[nums.length - 1];
for (int i = 0; i < nums.length; i++) {
min = min < pre ? min : pre;
temp = nums[i];
nums[i] = pre;
pre = temp;
}
return min;
}
方法一:二分搜索 O(logN)
/*
2 3 4 5 6 7
4 5 6 7 2 3 變化點:所有變化點的左側元素都大於數組第一個元素,變化點右側元素都小於數組第一個元素
7 2 3 4 5 6
找數組中間元素mid
如果中間元素 > 數組第一個元素, 我們需要在 mid 右邊搜索變化點。
如果中間元素 < 數組第一個元素,我們需要在 mid 左邊搜索變化點
當我們找到變化點時停止搜索,當以下條件滿足任意一個即可:
nums[mid] > nums[mid + 1],因此 mid+1 是最小值。
nums[mid - 1] > nums[mid],因此 mid 是最小值。
*/
public int findMin(int[] nums) {
if (nums.length == 1) return nums[0];
int left = 0, right = nums.length - 1;
if (nums[right] > nums[0]) return nums[0];
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] > nums[mid + 1]) return nums[mid + 1];
if (nums[mid - 1] > nums[mid]) return nums[mid];
if (nums[mid] > nums[0]) {
left = mid + 1;
}
if (nums[mid] < nums[0]) {
right = mid - 1;
}
}
return -1;
}