版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/z740852294/article/details/86470042
LeetCode 217. 存在重复元素 java
给定一个整数数组,判断是否存在重复元素。
如果任何值在数组中出现至少两次,函数返回 true。如果数组中每个元素都不相同,则返回 false。
示例 1:
输入: [1,2,3,1]
输出: true
示例 2:
输入: [1,2,3,4]
输出: false
示例 3:
输入: [1,1,1,3,3,4,3,2,4,2]
输出: true
JAVA 代码:
class Solution {
public boolean containsDuplicate(int[] nums) {
int n = nums.length;
if (n < 2) {
return false;
}
// 先排序
//方法一: 快排 三元取中+插入
quickSort(nums, 0, n - 1);
//方法二:三数取中+插排+聚集相同元素
// qsortThreeInsertGather(nums, 0, n - 1);
for (int i = 0; i < n - 1; i++) {
if ((nums[i] ^ nums[i + 1]) == 0 ? true : false) {
return true;
}
}
return false;
}
//三数取中+插排+聚集相同元素
public void qsortThreeInsertGather(int[] arr, int low, int high) {
if (high - low + 1 < 10) {
insertSort(arr, low, high);
return;
} // 插排,递归出口
partitionMedianOfThree(arr, low, high); // 三数取中
// 进行左右分组(处理相等元素)
int first = low;
int last = high;
int left = low;
int right = high;
int leftLength = 0;
int rightLength = 0;
int key = arr[first];
while (first < last) {
while (first < last && arr[last] >= key) {
if (arr[last] == key) // 处理相等元素
{
swap(arr, last, right);
right--;
rightLength++;
}
last--;
}
arr[first] = arr[last];
while (first < last && arr[first] <= key) {
if (arr[first] == key) {
swap(arr, first, left);
left++;
leftLength++;
}
first++;
}
arr[last] = arr[first];
}
arr[first] = key;
// 一次快排结束
// 把与基准元key相同的元素移到最终位置周围
int i = first - 1;
int j = low;
while (j < left && arr[i] != key) {
swap(arr, i, j);
i--;
j++;
}
i = last + 1;
j = high;
while (j > right && arr[i] != key) {
swap(arr, i, j);
i++;
j--;
}
qsortThreeInsertGather(arr, low, first - leftLength - 1);
qsortThreeInsertGather(arr, first + rightLength + 1, high);
}
public void quickSort(int[] arr, int low, int high) {
//数据很少 插入排序
if (high - low + 1 < 15)
{
insertSort(arr, low, high);
return;
}
// 三数取中
partitionMedianOfThree(arr, low, high);
// 将 >= x 的元素交换到右边区域,将 <= x 的元素交换到左边区域
int partition = partition(arr, low, high);
quickSort(arr, low, partition - 1);
quickSort(arr, partition + 1, high);
}
/// 三数取中确定基准元,将确定好的基准元与第一个数交换,无返回值
public void partitionMedianOfThree(int[] arr, int low, int high) {
int mid = low + (high + -low) / 2;
if (arr[mid] > arr[high]) {
swap(arr, mid, high);
}
if (arr[low] > arr[high]) {
swap(arr, low, high);
}
if (arr[mid] > arr[low]) {
swap(arr, mid, low);
} // 将中间大小的数与第一个数交换
}
public void swap(int[] nums, int index1, int index2) {
if (index1 == index2) {
return;
}
int temp = nums[index1];
nums[index1] = nums[index2];
nums[index2] = temp;
}
public int partition(int[] arr, int low, int high) {
int first = low;
int last = high;
int key = arr[low]; // 取第一个元素作为基准元
while (first < last) {
while (first < last && arr[last] >= key)
last--;
arr[first] = arr[last];
while (first < last && arr[first] <= key)
first++;
arr[last] = arr[first];
}
arr[first] = key; // 基准元居中
return first;
}
public void insertSort(int[] arr, int l, int r) {
// 从第二位开始 往前插入
for (int i = l + 1; i <= r; i++) {
int x = arr[i];
// 元素X应该插入的位置
int j;
for (j = i; j > l && x < arr[j - 1]; j--) {
arr[j] = arr[j - 1];
}
arr[j] = x;
}
}
}