19. 寻找峰值
题目很简单,如果是n的时间复杂度要求,直接遍历一遍即可:
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param nums int整型一维数组
* @return int整型
*/
public int findPeakElement (int[] nums) {
// write code here
if(nums.length==1) return 0;
else if(nums[0]>nums[1]) return 0;
else if(nums[nums.length-2]<nums[nums.length-1]) return nums.length-1;
for(int i = 1; i< nums.length-1; i++){
if(nums[i]>nums[i+1]&&nums[i]>nums[i-1]) return i;
}
return 0;
}
}
因为可以返回任意一个峰值,才可以使用二分法,才可以达到logn的时间复杂度。
每次划分中点,
- 如果nums[mid]>nums[mid+1],说明右边是向下的,减去右边的搜索范围,right=mid;
- 如果nums[mid]<nums[mid+1],说明右边是向上的,减去左边的搜索范围,left=mid+1
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param nums int整型一维数组
* @return int整型
*/
public int findPeakElement (int[] nums) {
// write code here
int left = 0;
int right = nums.length-1;
while(left<right){
int mid = (left+right)/2;
if(nums[mid]<nums[mid+1]) left = mid+1;
else right = mid;
}
return left;
}
}
20. 数组中的逆序对
哪怕是之前写过题解,该忘的还是会忘…
求输入数组中的逆序对的总数,可以采用分治思想的归并算法。
和归并排序没有任何不同,区别只在于在右边数组中的元素被取出时记录左边有多少个元素比当前大即可,因此时间复杂度为O(nlogn),空间复杂度O(N)
- 用mergeSort函数进行分组,每次递归都将当前数组一分为二;
- 用sort函数归并排序,在归并的同时计算逆序对的个数。每次都有左右两个数组进行归并,选择两个数组当前指向的数较小的那个,如果当前取出的数是右边数组中的,则左边数组所有剩下的数都比当前右边被取出的这个数大,此时逆数对应加上左边数组长度-左边当前下标
具体来说,当前输入数组为(3,1,4,5,2)
public class Solution {
int count = 0;
public int InversePairs(int [] array) {
int[] tmp = new int[array.length];//存放排序数组
mergeSort(array, 0, array.length-1, tmp);
return count;
}
public void mergeSort(int[] array, int begin, int end, int[] tmp){
int mid = (begin+end)/2;
if(begin<end){
mergeSort(array, begin, mid, tmp);
mergeSort(array, mid+1, end, tmp);
merge(array, begin, mid, end, tmp);
}
}
public void merge(int[] array, int begin, int mid, int end, int[] tmp){
int i = begin;
int j = mid+1;
int s = begin;
while(i<=mid&&j<=end){
if(array[i]<array[j]){
tmp[s++] = array[i++];
}
else{//右边数较小,存在逆序对,数量是左边数组长度-左边索引
tmp[s++] = array[j++];
count += mid+1-i;
count %= 1000000007;
}
}
while(i<=mid) tmp[s++] = array[i++];
while(j<=end) tmp[s++] = array[j++];
for(int k = begin; k<=end; k++){
array[k] = tmp[k];//把排好的更新到array中
}
}
}