6月29日的五题

215. 数组中的第K个最大元素

45. 跳跃游戏

46. 全排列

47. 全排列 II

48. 旋转图像

--------------------------------分界线-----------------------------------

215. 数组中的第K个最大元素

Difficulty: 中等

在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

示例 1:

输入: [3,2,1,5,6,4] 和 k = 2
输出: 5

示例 2:

输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4

说明:

你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。

Solution:随机快速排序

import java.util.Arrays;
import java.util.Random;

class Solution {
    public int findKthLargest(int[] nums, int k) {
        int res =  quickSort(nums, 0, nums.length-1, nums.length-k);

        return nums[res];
    }

    Random random = new Random();
    //找到第nums.length - k 大的元素的位置
    public int  quickSort(int[] nums, int l, int r, int k){
        if(l > r) return l;
        int flag = random.nextInt(r-l+1)+l;  //生成(l-r)之间的随机数
        swap(nums, l, flag);
        int i = l, j = r, partition = nums[l];
        while(i < j){
            while(i<j && nums[j]>=partition){
                j--;
            }
            if(i<j){
                swap(nums, i, j);
            }
            while(i<j && nums[i]<=partition){
                i++;
            }
            if(i<j){
                swap(nums, i, j);
            }
        }
        if(i == k) return i;
        else return i<k? quickSort(nums, i+1, r, k): quickSort(nums, l, i-1, k);
    }

    public void swap(int[] nums, int i, int j){
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }


}

45. 跳跃游戏 II

Difficulty: 困难

给定一个非负整数数组,你最初位于数组的第一个位置。

数组中的每个元素代表你在该位置可以跳跃的最大长度。

你的目标是使用最少的跳跃次数到达数组的最后一个位置。

示例:

输入: [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
     从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。

说明:

假设你总是可以到达数组的最后一个位置。

Solution:贪心算法

//贪心算法,一直找最远可以跳到我这个点的位置
class Solution {
    public int jump(int[] nums) {
        int len = nums.length;
        int index = len-1, res = 0;
        while(index > 0){
            for(int i=0; i<index; i++){
                if(index-i <= nums[i]){
                    res++;
                    index = i;
                    break;
                }
            }
        }
        return res;

    }

}

46. 全排列

Difficulty: 中等

给定一个 没有重复 数字的序列,返回其所有可能的全排列。

示例:

输入: [1,2,3]
输出:
[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]

Solution:回溯算法

import java.util.ArrayList;
import java.util.List;

//回溯
class Solution {
    public List<List<Integer>> permute(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        List<Integer> temp = new ArrayList<>();
        int[] used = new int[nums.length];
        backtrack(nums, res, temp, used);
        return res;

    }

    public void backtrack(int[] nums, List<List<Integer>> res, List<Integer> temp, int[] used){

        if(temp.size() == nums.length){
            res.add(new ArrayList<>(temp));
            return;
        }

        for(int i=0; i<nums.length; i++){
            if(used[i] == 1) continue;
            used[i] = 1;
            temp.add(nums[i]);
            backtrack(nums, res, temp, used);
            used[i] = 0;
            temp.remove(temp.size()-1);
        }

    }
}

47. 全排列 II

Difficulty: 中等

给定一个可包含重复数字的序列,返回所有不重复的全排列。

示例:

输入: [1,1,2]
输出:
[
  [1,1,2],
  [1,2,1],
  [2,1,1]
]

Solution:上一题的回溯算法,去重

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

//回溯
class Solution {
    public List<List<Integer>> permuteUnique(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> res = new ArrayList<>();
        List<Integer> temp = new ArrayList<>();
        int[] used = new int[nums.length];
        backtrack(nums, res, temp, used);
        return res;

    }

    public void backtrack(int[] nums, List<List<Integer>> res, List<Integer> temp, int[] used){

        if(temp.size() == nums.length){
            res.add(new ArrayList<>(temp));
            return;
        }

        for(int i=0; i<nums.length; i++){
            if(i!=0 && nums[i]==nums[i-1] && used[i-1]==1) continue;  //去重
            if(used[i] == 1) continue;
            used[i] = 1;
            temp.add(nums[i]);
            backtrack(nums, res, temp, used);
            used[i] = 0;
            temp.remove(temp.size()-1);
        }

    }

}

48. 旋转图像

Difficulty: 中等

给定一个 _n _× n 的二维矩阵表示一个图像。

将图像顺时针旋转 90 度。

说明:

你必须在旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。

示例 1:

给定 matrix = 
[
  [1,2,3],
  [4,5,6],
  [7,8,9]
],

原地旋转输入矩阵,使其变为:
[
  [7,4,1],
  [8,5,2],
  [9,6,3]
]

示例 2:

给定 matrix =
[
  [ 5, 1, 9,11],
  [ 2, 4, 8,10],
  [13, 3, 6, 7],
  [15,14,12,16]
], 

原地旋转输入矩阵,使其变为:
[
  [15,13, 2, 5],
  [14, 3, 4, 1],
  [12, 6, 8, 9],
  [16, 7,10,11]
]

Solution:一次交换四个位置

/*
固定四个角

  (low, low)    (low, high)

  (high, low)   (high, high)

一圈为一个循环

*/
class Solution {

    public void rotate(int[][] matrix) {
        int n = matrix.length, count;
        int low = 0, high = n-1;
        for(int i=0; i<n/2; i++){  //圈数
            low = i;
            high = n-i-1;
            for(int j=0; j<high-low; j++){   //遍历第一行,每次交换四个元素
                int temp = matrix[low][low+j];
                matrix[low][low+j] = matrix[high-j][low];
                matrix[high-j][low] = matrix[high][high-j];
                matrix[high][high-j] = matrix[low+j][high];
                matrix[low+j][high] = temp;
            }
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章