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;
  }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章