n+1个范围是0~n的数字,找出所有重复的数字,O(n)基础上不用额外空间。
算法思想:
使用数组的值对应数组的下标,出现多对一的则说明重复。
算法:
遍历数组,每次访问前判断数组是否访问过(访问过的会被置为负数);
如果没访问过,则以当前数组的值为数组下标,访问其值:
若为负数,则此元素被访问过,即数组下标在数组值中多次出现,重复;
若非负,则此元素没被访问过,将其标记为访问过(取负值,0取数组长度的负 值);
如果访问过(访问过的数为负数),则再取负为数组下标(如果是数组长度,表明是0),访问其值:
若为负数,则此元素被访问过,即数组下标在数组值中多次出现,重复;
若非负,则此元素没被访问过,将其标记为访问过(取负值,0取数组长度的负 值)。
算法如下:
public static void alg(int[] array){
for(int i=0;i<array.length;i++){
if(0>array[i]){
if(-array.length == array[i]){
if(0>array[0])
System.out.println(0);
}
else if(0>array[-array[i]]){
System.out.println(-array[i]);
}
else{
if(0 == array[-array[i]])
array[-array[i]] = -array.length;
else if(array[-array[i]]>0)
array[-array[i]]=-array[-array[i]];
}
}
else{
if(0>array[array[i]]){
System.out.println(array[i]);
}
else{
if(0 == array[array[i]])
array[array[i]] = -array.length;
else if(array[array[i]]>0)
array[array[i]]=-array[array[i]];
}
}
}
}
测试如下:
public static void main(String[] args) {
int[] array = new int[100];
/* array[0] = 1;
array[1] = 2;
array[2] = 0;
array[3] = 4;
array[4] = 0;*/
for(int i=0;i<100;i++)
array[i]=i;
array[5]=0;
array[1] = 1;
array[3] = 1;
array[89] = 80;
alg(array);
}
分享到:
相关推荐
总结来说,解决"找出数组3个数字相加为0的组合"的问题,需要掌握排序、双指针以及避免重复解的基本技巧。这种问题不仅考验程序员的基础知识,也锻炼了他们在面对实际问题时设计和优化算法的能力。
设计一个 O(n) 的最坏情况时间复杂度的算法来找出上述集合中在给定链表中缺失的那个元素。 #### 解决方案: 注意到存在 n + 1 个数字,但链表中只有 n 个数字。已知 0 到 n 的所有整数之和为 \(\frac{n(n + 1)}{2}\...
问题描述:在一个长度为 n 的数组里的所有数字都在 0 到 n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字是重复的,也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 解题思路:要求时间...
要求设计一个算法找出重复的数字,同时要求辅助空间复杂度为O(1)。这个问题可以通过使用异或操作来解决。异或操作有以下特性: 1. 相同的数异或结果为0。 2. 0与任何数异或都等于该数本身。 3. a^b^a=b;a^b^b=a。 ...
- 本题的目标是对于给定的一个正整数\( n \),找出所有可能的不同分解方式的数量。 #### 二、时间与空间限制 - **时间限制**: 3000毫秒(即3秒)。 - **内存限制**: 65536K(即64MB)。 #### 三、问题描述 - 题目要求...
【数组中找第一个重复数字】 在给定的数组中寻找第一个重复的数字是常见的编程面试问题。有三种方法可以解决这个问题: 1. **哈希表方法**:利用一个与原数组大小相同的哈希表(或数组)作为标记,遍历数组,如果...
给定一个长度为n的数组nums,其中所有元素的值都在0到n-1之间,题目要求找出任意一个重复的数字。这里我们讨论四种不同的解决方案。 **方法一:哈希集合** 我们可以使用哈希集合(例如Java中的HashSet)来解决这个...
C#实现中,通常结合计数排序多次进行处理,时间复杂度为O(d*(n+k)),d为数字位数,k为数字范围。 在实际开发中,选择合适的排序算法要考虑数据规模、是否允许额外空间以及稳定性等因素。C#提供的`Array.Sort()`方法...
**题解**: 给定一个整数数组 `nums` 和一个目标值 `target`,找出数组中和为目标值的两个整数。 **算法**: - 使用哈希表记录每个元素出现的位置。 - 遍历数组,对于每个元素 `nums[i]`,检查 `target - nums[i]` ...
选择排序每次找出未排序部分的最小(或最大)元素,然后将其与第一个未排序的位置进行交换。这个过程会重复n-1次,直到整个序列有序。时间复杂度同样是O(n^2)。 3. 插入排序(Insertion Sort) 插入排序将每个元素...
其时间复杂度始终为O(n log n),但需要额外的内存空间。 6. 堆排序(Heap Sort) 堆排序利用了二叉堆的数据结构,将待排序的数组构造成一个大顶堆(或小顶堆),然后将堆顶元素与末尾元素交换,再调整堆,重复此...
为了优化,我们可以考虑使用排序,例如先对数组进行快速排序,然后遍历一次数组计算相邻元素之间的差值,找出最小值,这样可以在O(n log n)时间内完成。 7. **排序算法**:1.3题的a部分讨论了一种特殊的排序算法,...
- **空间复杂度**:\(O(n)\),需要额外的空间来存储中间结果。 - **排序趟数**:\(\log_2 n\)趟。 - **稳定性**:稳定排序。 #### 基数排序 - **定义与特点**:基数排序是一种非比较型整数排序算法,通过将整数按...
时间复杂度为O(n+k),其中k是数值范围,但不适用于大范围的整数。 8. 桶排序(Bucket Sort) 桶排序将数据分布到多个桶里,每个桶内部进行排序,然后按顺序依次合并所有桶中的元素。适用于数据均匀分布的情况,时间...
时间复杂度为O(n+k),其中k为数值范围。 8. 桶排序(Bucket Sort) 桶排序将数据分到有限数量的桶里,每个桶再分别排序。它适合数据均匀分布的情况,平均时间复杂度为O(n + k),其中k为桶的数量。 9. 基数排序...
时间复杂度为O(n+k),其中k为数的最大值,不适用于大数据范围。 8. 桶排序(Bucket Sort) 桶排序将数据分到有限数量的桶里,每个桶再单独排序。如果数据均匀分布,它能在O(n + k)的时间内完成,但若数据分布不均,...
基数排序适用于处理基数较大的整数数组,时间复杂度为线性的O(d*(n+r)),其中d是数字的位数,r是桶的数量。 这些排序算法各有优缺点,适用于不同的场景。在实际编程中,选择合适的排序算法对于程序性能至关重要。...
给定一个包含正整数和负整数的数组,要求找出子数组的最大和(时间复杂度为O(N),类似于Kadane算法)。用C语言编写一个函数实现该功能。 **解析**: 这是一个经典的动态规划问题,通常使用Kadane算法解决。Kadane...
插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。 6. **合并排序**:合并排序是一种分治策略...