Learn && Live
虚度年华浮萍于世,勤学善思至死不渝
前言
Hey,欢迎来到Connor的算法练习室,这个系列记录了我的算法练习过程,欢迎各位大佬阅读斧正!原创不易,转载请注明出处:http://t.csdn.cn/nWv6F,话不多说我们马上开始!
剑指 Offer 03. 数组中重复的数字⭐️
找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
示例 1:
输入:
[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3
限制:
2 <= n <= 100000
解题思路:
1.暴力解
没啥好说的,套娃套起来,反正不用指定输出哪个
class Solution {
public int findRepeatNumber(int[] nums) {
int result = 0;
boolean flag = false;
for(int i = 0; i < nums.length; ++i) {
for(int j = i + 1; j < nums.length; ++j) {
if(nums[i] == nums[j]) {
result = nums[i];
flag = true;
break;
}
}
if(flag) {
break;
}
}
return result;
}
}
2.原地交换
分析:
1.由题目可知,数组中元素的 索引 和 值 是 一对多 的关系
2.遍历数组并交换元素,使元素的索引与值一一对应 num[i] = i,起到与 字典 等价的作用
思路:
1.若 num[i] = i,正好,不用换
2.若 num[num[i]] = num[i],有重复值,返回num[i]
3.否则,交换索引为 i 的值和索引为 num[i] 的值
class Solution {
public int findRepeatNumber(int[] nums) {
for(int i = 0; i < nums.length;) {
if(nums[i] == i) {
i++;
continue;
}
if(nums[nums[i]] == nums[i]) return nums[i];
int temp = nums[i];
nums[i] = nums[temp];
nums[temp] = temp;
}
return -1;
}
}
剑指 Offer 21. 调整数组顺序使奇数位于偶数前面⭐️
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数在数组的前半部分,所有偶数在数组的后半部分。
示例:
输入:nums = [1,2,3,4]
输出:[1,3,2,4]
注:[3,1,2,4] 也是正确的答案之一。
提示:
0 <= nums.length <= 50000
0 <= nums[i] <= 10000
解题思路:
思路很简单,双向奔赴的对撞指针,一个指向头一个指向尾,满足各自的条件即移动,否则交换。
class Solution {
public int[] exchange(int[] nums) {
int left = 0;
int right = nums.length - 1;
while(left < right) {
// 奇数在左侧
while(left < right && nums[left] % 2 == 1) left++;
// 偶数在右侧
while(left < right && nums[right] % 2 == 0) right--;
// 否则交换
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
}
return nums;
}
}
剑指 Offer 39. 数组中出现次数超过一半的数字⭐️
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例:
输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
输出: 2
限制:
1 <= 数组长度 <= 50000
解题思路:
1.暴力
双循环嵌套,复杂度O(n²),超时
2.排序
思路:先将数组排序 Arrays.sort() ,中位数即为出现次数超过一半的数字(真的很牛很巧妙)
class Solution {
public int majorityElement(int[] nums) {
Arrays.sort(nums);
return nums[nums.length / 2];
}
}