Java算法分析1—————寻找数组相同元素

算法的两个评测指标:运行时间和内存消耗

要么用时间换空间,要么用空间换时间

寻找数组相同元素测试一:

0~99共100个元素各不相同,新加入一个0~99的元素不明确位置

从101个元素数组中找出与0~99元素中重复的一个

/* 找相同元素
 * 0~99共100个元素各不相同
 * 从101个元素数组中找出与0~99元素中重复的一个
 */
public class Dome01 {
	public static void main(String[] args) {
		int arr[] = new int[101];
		for (int i = 0; i < 100; i++) {
			arr[i] = i;
		}
		arr[100] = 38; // 假定重复元素为38
		// 将数组元素打乱 Math.random() 取值范围是[0,1)

		// 如何打乱数据??
		for (int j = 0; j < 1000; j++) { // 进行1000次数据打乱的操作
			int num1 = (int) (Math.random() * 101); // num取值范围是[0,101)
			int num2 = (int) (Math.random() * 101);
			int temp = arr[num1];
			arr[num1] = arr[num2];
			arr[num2] = temp;
		}

		// 算法一:用双循环实现
		Jonney: for (int i = 0; i < arr.length; i++) {
			// 将数组元素依次与后面的数组元素比较
			for (int j = i + 1; j < arr.length; j++) {
				if (arr[i] == arr[j]) {
					System.out.println("重复元素是:" + arr[i]);
					break Jonney; // 退出双循环
				}
			}
		}
		// 算法一效率太低

		// 算法二:将数组的元素全部累加起来就是0~99的数据+相同元素 再减去0~99的和
		int sum = 0;
		for (int i = 0; i < arr.length; i++) {
			sum += arr[i];
		}
		for (int j = 0; j < 100; j++) {
			sum -= j;
		}
		System.out.println("重复元素是:" + sum);
		// 算法二如果计算的数据太多就会有数据溢出

		// 算法三:使用异或解决
		// 0^1^2^3^4^...^m...^99^m^0^1^2^3^4^...^m...^99=m
		// 使用数组的第一个元素异或后面的所有元素
		for (int i = 1; i < arr.length; i++) {
			arr[0] = arr[0] ^ arr[i];
		}
		// 再次将arr[0]保存的结果与0~99异或一次
		for (int i = 0; i < 100; i++) {
			arr[0] = arr[0] ^ i;
		}
		System.out.println("重复元素是:" + arr[0]);
		// 算法三才是最佳算法
	}
}

寻找数组相同元素测试二:

0~99共100个整数,各不相同,将所有数放入一个数组,随机排布

数组长度100,将其中任意一个数替换成0~99另一个数(唯一重复的数字)

将重复的数字找出

/*
 * 0~99共100个整数,各不相同,将所有数放入一个数组,随机排布
 * 数组长度100,将其中任意一个数替换成0~99另一个数(唯一重复的数字)
 * 将重复的数字找出
 */
public class Dome2 {

	public static void main(String[] args) {
		int arr[] = new int[100];
		for (int i = 0; i < arr.length; i++) {
			arr[i] = i;
		}
		// 随机排布
		for (int i = 0; i < 1000; i++) {
			int num1 = (int) (Math.random() * 100);
			int num2 = (int) (Math.random() * 100);
			int temp = arr[num1];
			arr[num1] = arr[num2];
			arr[num2] = temp;
		}
		// 用某个值给某个值替换
		int num1 = (int) (Math.random() * 100);
		int num2 = (int) (Math.random() * 100);
		// 保证num1与num2不同
		while (num1 == num2) {
			num1 = (int) (Math.random() * 100);
		}
		System.out.println("将" + num1 + "位置的值用" + num2 + "的位置替换");
		arr[num1] = arr[num2];
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i] + "\t");
		}

		// 算法实现:
		// 算法一:用双循环实现
		Jonney: for (int i = 0; i < arr.length; i++) {
			// 将数组元素依次与后面的数组元素比较
			for (int j = i + 1; j < arr.length; j++) {
				if (arr[i] == arr[j]) {
					System.out.println("重复元素是:" + arr[i]);
					break Jonney; // 退出双循环
				}
			}
		}
		// 算法一效率太低

		// 算法二:用数组优化的算法
		// 定义一个新数组 int newArr[]=new int[100] 默认值为0
		// 把原始数组的元素作为新数组的下标,如果该下标对应的新数组元素存在,就将该元素值+1=1
		/*
		 * 原始数组         8 3 7 2 1 5 6 8 0
		 * 新数组           0 0 0 0 0 0 0 0 0
		 * 对新数组+1       1 1 1 1 0 1 1 1 2
		 */
		// 新数组中元素为2的值的下标就是重复元素
		int newArr[] = new int[100];
		for (int i = 0; i < arr.length; i++) {
			newArr[arr[i]]++; // 将原始元素对于新数组的索引下标
			if (newArr[arr[i]] == 2) {
				System.out.println("重复元素是:" + arr[i]);
			}
		}

	}

}

PS:测试二中的新定义个新数组的数组优化算法,虽然加快了查询速度,但也加大了内存开销

时间: 2024-10-09 00:37:58

Java算法分析1—————寻找数组相同元素的相关文章

LeetCode第三十五题-寻找数组中对应目标值的首尾索引

Search Insert Position 问题简介:寻找数组中元素与target的关系 注: 1.target小于数组所有元素时返回0 2.target大于数组所有元素时返回数组长度 3.target不包含于数组元素中,但取值区间在其中,返回对应的索引 举例: 1: 输入: [1,3,5,6], 5 输出: 2 2: 输入: [1,3,5,6], 2 输出: 1 3: 输入: [1,3,5,6], 7 输出: 4 4: 输入: [1,3,5,6], 0 输出: 0 解法一:比较简单的解法就是

有序数组寻找中位数以及寻找K大元素

问题描述: 两个排序的数组A和B分别含有m和n个数,找到两个排序数组的中位数,要求时间复杂度应为O(log (m+n)).转化成找到两个数组的第K大数字进行解决 解题方法: 对于一个长度为n的已排序数列a,若n为奇数,中位数为a[n / 2 + 1] , 若n为偶数,则中位数(a[n / 2] + a[n / 2 + 1]) / 2如果我们可以在两个数列中求出第K小的元素,便可以解决该问题不妨设数列A元素个数为n,数列B元素个数为m,各自升序排序,求第k小元素取A[k / 2] B[k / 2]

【算法31】寻找数组的主元素(Majority Element)

题外话 最近有些网友来信问我博客怎么不更新了,是不是不刷题了,真是惭愧啊,题还是在刷的,不过刷题的频率没以前高了,看完<算法导论>后感觉网上很多讨论的题目其实在导论中都已经有非常好的算法以及数学证明,只是照搬的话好像意义也不是很大,希望找到些有代表性的题目在更新,另外希望能接着前面的<穷举递归和回溯算法终结篇>一系列如动态规划.贪心算法类的终结篇,在梳理自己知识结构的同时也能够帮助读者们更系统的学习算法思想.好了话不多说,进入正题. 问题描述 给定一个数组A[n], 定义数组的主元

Java实现升序排列的整形数组A,元素两两不相等找出A[i]=i的数据

import java.util.ArrayList; //升序排列的整形数组A,元素两两不相等.请设计高效的算法找出A[i]=i的数据. //使用二种方法 public class BinarySearch { public static void main(String[] args) {     int[] nums={-1,1,2,3};     ArrayList<Integer> res=find(nums);     for(int e:res){      System.out

Java比较两个数组中的元素是否相同的最简单方法

呵呵呵,实现Java比较两个数组中的元素是否相同的功能你是怎么做的?看下面最简单方法: import java.util.Arrays; public class Test { /** * Java比较两个数组中的元素是否相同 */ public static void main(String[] args) { String [] array1 = {"1","2","3"}; String [] array2 = {"3"

寻找数组中的第K大的元素,多种解法以及分析

遇到了一个很简单而有意思的问题,可以看出不同的算法策略对这个问题求解的优化过程.问题:寻找数组中的第K大的元素. 最简单的想法是直接进行排序,算法复杂度是O(N*logN).这么做很明显比较低效率,因为不要求别的信息只要计算出第K大的元素.当然,如果在某种情况下需要频繁访问第K大的元素就可以先进行一次排序在直接得出结果. 第一种方式是这样,用选择排序,冒泡法,或者交换排序这类的排序,对前K个元素进行排序.这三种算法也许不是最快的排序算法.但是都有个性质:计算出最大(小)的元素的算法复杂度是O(N

【java】为数组全部元素赋同样的值 以及 数组之间的复制

为数组全部元素赋同样的值 : boolean[] resArray=new boolean[100]; Arrays.fill(resArray, true); 数组之间的复制: System.arraycopy(Object src, int srcPos, Object dst, int dstPos, int length) src:源数组: srcPos:源数组要复制的起始位置: dest:目的数组. destPos:目的数组放置的起始位置: length:复制的长度. 注意:src a

【java】为数组所有元素赋相同的值 以及 数组之间的复制

为数组所有元素赋相同的值 : boolean[] resArray=new boolean[100]; Arrays.fill(resArray, true); 数组之间的复制: System.arraycopy(Object src, int srcPos, Object dst, int dstPos, int length) src:源数组: srcPos:源数组要复制的起始位置: dest:目的数组: destPos:目的数组放置的起始位置: length:复制的长度. 注意:src a

Java实现找出数组中重复次数最多的元素以及个数

/**数组中元素重复最多的数 * @param array * @author shaobn * @param array */ public static void getMethod_4(int[] array){ Map<Integer, Integer> map = new HashMap<>(); int count = 0; int count_2 = 0; int temp = 0; for(int i=0;i<array.length;i=i+count){