1
解法1:定义新数组计数 解法2:排序后枚举
public int repeatedNTimes(int[]nums){
//nums.length == 2 * n.
// nums 包含 n + 1 个 不同的 元素
//nums 中恰有一个元素重复 n 次
//返回重复了n次的那个元素
int[]arr=new int[10001];
for (int x:nums) {
arr[x]++;//将数字为i的重复次数记录在arr里
}
for (int i = arr.length-1; i >=0; i--) {
if(arr[i]==nums.length/2){
return i;
}
}
return 0;
}
public int repeatedNTimes3(int[]nums){
//分为几种情况进行讨论
//排序之后由于nums占一半位置,则只有以下
//可能[1111|2345] //[1234|5555] //[1233|3345]
Arrays.sort(nums);
if(nums[0]==nums[nums.length/2-1]){
return nums[0];
}
else if(nums[nums.length/2]==nums[nums.length-1]){
return nums[nums.length-1];
}
else{
return nums[nums.length/2-1];
}
}
解法1:for循环遍历左右边界
解法2:栈去存左边界,遍历右边界
还可以双指针迭代
public int maxWidthRamp2(int[] nums) {//时间复杂度较高
int count=0;
//最外侧的j固定,左边界i固定
for (int j=nums.length-1; j >=0; j--) {
for (int i = 0; i < j; i++) {
if(nums[j]>=nums[i]){//条件满足,进行比较
count=Math.max(count,j-i);
}
}
}
return count;
}
public int maxWidthRamp1(int[] nums) {
//上面代码的时间复杂度为M*N,优化
//i排序通过栈来进行一个排序,满足条件的最大值放下面,最小值放上面
//0下标是最小的也不影响,j-0则最大
Stack<Integer> stack=new Stack<>();
int count=0;
for (int i = 0; i <nums.length ; i++) {
if (stack.isEmpty() || nums[stack.peek()] > nums[i]) {
//这里不取等号,取等则可能导致下一位的j-i少1
stack.push(i);//栈里元素由里到外,降序排列
}
}
for (int j = nums.length-1; j >=0 ; j--) {
//右边界固定,左边界变化去取,如果没找到则右边界向左靠近
while (!stack.isEmpty()&&nums[stack.peek()]<=nums[j]){
//这里需要取等,题干要求
int i=stack.pop();
count=Math.max(count,j-i);
}
}
return count;
}