1、将数组中的奇数置换到偶数前面(时间复杂度为O(n))
算法设计思路:
我们可以在数组前端和末端各自定义一个索引,从数组两边同时向中间开始查找:
int i = 0;
int j = a.length-1;
for (;i<j;){
if (i < j && a[i] % 2 != 0){
i ++;
}
if (i < j && a[j] % 2 == 0){
j --;
}
如果左边的数字是奇数,那么左边就自动向右查找下一个元素,直到找到的数字为偶数是停止,右边也相同的方法挨个向左查找元素,直到找到奇数就停下来。
if (i<j);{
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
这个时候交换找到的两个数,就能够实现将奇数放在偶数前了。
代码实现
import java.util.Arrays;
public class substitution {
public static void main(String[] args) {
int[] a = {1,2,3,5,4,6,7,8,9,2,4,1};
int i = 0; //定义左边的索引,从下标为0的元素开始
int j = a.length-1; //定义右边的索引,从最后一个元素开始
for (;i<j;){
if (i < j && a[i] % 2 != 0){ //如果左边的数为奇数的话
i ++; // i 向右指向下一个元素
}
if (i < j && a[j] % 2 == 0){ //如果右边的数为偶数的话
j --; //向左指向下一个元素
}
if (i<j);{ //交换两边数的值
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
System.out.println(Arrays.toString(a));
}
}
2、在数组中找到两个数,使其相加等于输入的key
算法设计思路:
要使两个数相加等于key,所以我们可以先确定一个数,然后在数组中寻找,看数组中是否存在另一个数,使这两个数的和等于key。 可以先定义一个变量temp,然后遍历一遍这个数组,每次用key减去,把得到的值赋给temp。
int temp = 0;
for (; i < a.length - 1; i++) {
temp = key - a[i];
然后再从下一个元素开始遍历一次数组,寻找是否存在另一个数等于temp,这样就可以解决这个问题了。
for (j = i + 1; j < a.length; j++) {
if (temp == a[j]) {
System.out.println(key + “等于第” + (i + 1) + “个与第” + (j + 1) + “个数的和”);
}
代码实现
import java.util.Scanner;
public class fibonacci {
public static void main(String[] args) {
int[] a = {1, 2, 3, 4, 5, 6, 7, 8, 9};
Scanner scanner = new Scanner(System.in);
int key = scanner.nextInt(); //输入key的值
int i = 0;
int j;
int temp = 0;
for (; i < a.length - 1; i++) { //遍历一遍数组
temp = key - a[i]; //确定要寻找的数的值
for (j = i + 1; j < a.length; j++) { //开始查找temp
if (temp == a[j]) { //如果找到,就输出出来
System.out.println(key + "等于第" + (i + 1) + "个与第" + (j + 1) + "个数的和");
}
}
}
}
}
3、一个整形数组,除了两个数字只出现一次外,其他数字都是两次。{2,3,1,3,4,1} 找到这两个数字
算法设计思路:
解决这个问题,首先我们可以对数组进行排序,这样相同的数字肯定是相邻的,然后遍历一遍,找出和前后数字都不同的数字,就得到了要找的数。首先我们另外定义一个数组,这个数组里存放的是出现了两次的元素,因为原数组只有两个数字是单独出现的,所以新定义的数组长度为2。
for (;i<a.length-1;i++){
if (a[i] != a[i+1] && a[i] != a[i-1]){
System.out.print(a[i]+" ");
}
}
然后我们要得到出现两次的元素的下标,通过两次遍历原数组的方式,就能够得到要找的数字了。
代码实现
import java.util.Arrays;
public class fibonacci {
public static void main(String[] args) {
int[] a = {2, 3, 1, 3, 4, 1,5,5};
Arrays.sort(a); //对原数组进行排序
int[] b = new int[ 2]; //新定义的数组长度
int i = 1;
for (;i<a.length-1;i++){
if (a[i] != a[i+1] && a[i] != a[i-1]){ //如果一个数与它前一个数和后一个数都不同,则找到了
System.out.print(a[i]+" ");
}
}
}
}
4、熟悉Arrays类里的方法
经过多次查看这个类里的方法和源码,我理解了一些Arrays类里的一些方法,列举一些我比较了解的常用的方法:
1、toString方法
源码:
public static String toString(float[] a) {
if (a == null)
return "null";
int iMax = a.length - 1;
if (iMax == -1)
return "[]";
StringBuilder b = new StringBuilder();
b.append('[');
for (int i = 0; ; i++) {
b.append(a[i]);
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
}
toString方法的作用在我看来,就是能够输出数组中所有的元素,并且能用数组的形式表现出来。
2、binarySearch方法
源码:
public static int binarySearch(long[] a, int fromIndex, int toIndex,
long key) {
rangeCheck(a.length, fromIndex, toIndex);
return binarySearch0(a, fromIndex, toIndex, key);
}
// Like public version, but without range checks.
private static int binarySearch0(long[] a, int fromIndex, int toIndex,
long key) {
int low = fromIndex;
int high = toIndex - 1;
while (low <= high) {
int mid = (low + high) >>> 1;
long midVal = a[mid];
if (midVal < key)
low = mid + 1;
else if (midVal > key)
high = mid - 1;
else
return mid; // key found
}
return -(low + 1); // key not found.
}
binarySearch方法就是实现二分查找的方法,但是查找的数组必须有序,并且查找的数字要存在此数组中,将要查找的元素值,先与数组的中间值进行比较:如果等于中间值,则直接返回结果;如果小于中间值,则要查找的元素值必在前面一段的子数组中;如果大于中间值,则要查找的元素值必有后面一段的子数组中。
3、sort方法
sort方法在目前我用的范围内,是一个快速排序算法,但其实这个方法并不是看起来这么简单,它根据元素个数的不同,而采用了不同的排序方法。
4、copyOf方法
源码:
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
从代码可知,数组拷贝时调用的是本地方法 System.arraycopy() ; Arrays.copyOf()方法返回的数组是新的数组对象,原数组对象仍是原数组对象,不变,该拷贝不会影响原来的数组。
5、如何排序数组并插入某个元素?
Java中的八种排序方法:
(1)、冒泡排序
比较相邻的元素。如果第一个比第二个大,就交换他们两个。对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。针对所有的元素重复以上的步骤,除了最后一个。持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
方法实现:
public static void bubbleSort(int[] arr) {
int temp = 0;
int size = arr.length;
for (int i = 0; i < size - 1; i++) {
for (int j = 0; j < size - 1 - i; j++) {
if arr[j] > arr[j + 1]) //交换两数位置
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
(2)、快速排序
通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分关键字小,则分别对这两部分继续进行排序,直到整个序列有序。
代码实现
public static int getMiddle(int[] arr, int low,int high)
{
int temp =arr[low]; //确定一个中间数
while(low < high)
{
while(low < high &&arr[high] > temp) //把比中间数小的记录移到低端
{
high--;
}
arr[low] = arr[high]
while(low < high &&arr[low] < temp) //把比中间数小的记录移到低端
{
low++;
}
arr[high] =arr[low] ;
}
arr[low] = temp ;
return low ; // 返回中间值的的位置
}
此外还有 希尔排序,插入排序,选择排序,归并排序,堆排序,基数排序。
对于已经排序好的数组如何在正确的位置插入数字这个问题,首先想到的是将数组a中m位置以后的元素整体先后移动一个位置,然后将待插入的元素赋值给a[m-1]。
代码实现:
import java.util.Arrays;
public class intnum {
public static void main(String[] args){
int a[] = new int[]{1,2,3,4,5,7,8,9};
int n = a.length; //数组长度
int i;
int j;
int p = 6; //要插入的数
int d[] = new int[n+1]; //新定义一个数组,这个数组用来接收插进来的数之后的数组
for(i=n-1;i>=0;i--){ //插入前先寻找位置
if(p<=a[i]){
d[i+1]=a[i];
}
if(p>a[i]){ //插入后排序
d[i+1]=p;
for(;i>=0;i--){
d[i]=a[i];
}
break;
}
}
System.out.println(Arrays.toString(d));
}
}
6、找出数组中最大和最小的元素
算法设计思路:
我们可以先对数组进行一次排序,这样最小的元素就排在了第一位,最大的元素就排在了最后,最后输出就行了。
public static void main(String[] args) {
int[] a = {1,2,3,4,5,6,7,8,9};
Arrays.sort(a); //对原数组进行排序
int min = a[0]; // 最小的
int max = a[a.length-1]; //最大的
System.out.print(min+" "+max);
}
7、如何合并两个数组
算法设计思路:
首先我们要对数组进行扩容,我们可以用拷贝来进行操作,将两个数组的长度和元素通过Arrays.copyOf和System.arraycopy来实现。
arr1 = Arrays.copyOf(arr1, arr1.length+arr2.length);
System.arraycopy(arr2, 0, arr1, arr1.length,arr2.length);
System.out.println(Arrays.toString(arr1));
代码实现:
import java.util.Arrays;
public class arrayssum {
public static void main(String[] args){
int[] arr1 = {1,2,3,4,5}; //第一个数组
int[] arr2 = {6,7,8,9}; //第二个数组
int i = arr1.length; //第一个数组长度
int j = arr2.length; //第二个数组长度
int[] arr3 = Arrays.copyOf(arr1, i+j); // 合并后的数组,拷贝第一个数组数据
System.arraycopy(arr2, 0, arr3, arr1.length,arr2.length); //将第二个数组里的数据拷贝
System.out.println(Arrays.toString(arr3)); //输出
}
}
8、如何填充数组
我们要对一个一维数组进行快速填充,可以利用Arrays类里的fill方法,其源码是:
public static void fill(int[] a, int val) {
for (int i = 0, len = a.length; i < len; i++)
a[i] = val;
}
其中,参数 int[] a 就是我们需要填充的数组,val就是要填充的数字,底层代码是通过一次for循环来依此赋值的。
代码实现:
import java.util.Arrays;
public class fillArray {
public static void main(String[] args) {
int[] a = new int[10];
Arrays.fill(a, 10);
System.out.println(Arrays.toString(a));
}
}
9、如何在数组中查找常见元素?
1、我们可以遍历一遍整个数组,然后通过判断语句查找。
2、可以用二分法查找,不过在查找之前必须先对数组排好序。
例如:
public class fibonacci {
public static void main(String[] args) {
int[] a = {1,2,3,4,5,6,7,8,9};
for (int i = 0;i < a.length;i ++ ) {
if (a[i] == 6) { //我们要查找 6
System.out.print(a[i]); //如果在就输出
}else {
System.out.println("不在该数组里"); //如果不在就说明
}
}
}
}
10、如何删除数组中的一个元素
算法设计思路:
我们可以把要删除的元素和数组最后一个元素进行互换,然后用一个新的数组将原数组除了最后一个元素以外的元素进行拷贝,最后得到的数组就是删除元素后的数组。
代码实现
public static void main(String[] args) {
int[] a = {1,2,3,4,5,6,7,8,9};
System.out.println("要删除第几个元素?");
Scanner scanner = new Scanner(System.in);
int i = scanner.nextInt();
int m = a[a.length-1]; //要删除的元素和数组最后一个元素进行互换
a[a.length-1] = a[i - 1];
a[i - 1] = m;
int[] b = Arrays.copyOf(a,a.length-1); //将原数组除了最后一个元素以外的元素进行拷贝
System.out.print(Arrays.toString(b));
}