189. 旋轉數組, 尋找旋轉排序數組中的最小值

  1. 旋轉數組 給定一個數組,將數組中的元素向右移動 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;
  }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章