2022.1.6 时间复杂度及简单排序算法
-
定义:在常数操作数量的表达式中,除去低阶项和高阶项的系数所剩下来的东西,记作O(剩下),读作 big O(剩下),时间复杂度按照算法执行的最差情况估计;
-
评价一个算法流程的好坏,先看时间复杂度的指标,然后再分析不同数据样本下的* 实际运行时间 *,也就是”常数运行时间“。
2. 简单排序算法
(1)选择排序
-
从数组下标为零的位置(比较的数)开始,依次与后面n-1个数(被比较的数)进行比较,找到最小的数并放在比较的数。
-
代码:
public class selectionSoft {
public static void main(String[] args)
{
int[] arr = {4,6,2,9,4,8,6,4,5,7,1};
SelectionSoft(arr);
}
public static void SelectionSoft(int[] arr)
{
for(int i=0;i<arr.length;i++)
{
for(int j=i+1;j<arr.length;j++)
{
if(arr[j]<arr[i])
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
for(int i:arr)
{
System.out.print(i+" ");
}
}
}
-
运行结果:
(2)冒泡排序:从第i个数一直到n-1个数上一直找最小值或最大值,交换。
(3)插入排序:
-
code:
public static void insertionSoft(int[] arr)
{
for(int i=1;i<arr.length;i++)
{
for(int j=i-1;j>=0;j--)
{
if(arr[j]>arr[j+1])
{
int temp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = temp;
}
}
}
for(int cur:arr)
System.out.print(cur+" ");
}
3.异或
(1)可以实现两个数的值进行交换
int a=1,b=2;(a,b的值必须在内存中为两块不同的区域)
a = a^b; //a = 1^2,b = 2
b = a^b; //a = 1^2,b = 1^2^2 = 1^0 = 1
a = a^b; //a = 1^2^1 = 0^2 = 2,b=1;
(2) 寻找n个数中出现了奇数次的数
-
eg:在n个数中,只有一种数出现了奇数次,其他的数都出现了偶数次,找出这个数。
//假设这n个数为arr[1]~arr[n];
main()
{
int eor = 0;
for(int i=1;i<=n;i++)
{
eor = eor^arr[i];
}
System.out.println(eor);//最后异或完的eor即为这组数中唯一一个出现了奇数次的数。
} -
eg:在n个数中,有两种数出现了奇数次,其他的数都出现了偶数次,找出这两个数。
public static void main(String[] args)
{
int[] arr = {4,6,2,9,4,8,6,4,7,9,7,8};
printOddTimesNum(arr);
}
printOddTimesNum(int[] arr)
{
int eor = 0;
for(int cur:arr)
{
eor^=cur;
}
//此时eor为这两个要求的数的异或,eor!=0。
//eor!=0,这两个出现了奇数次的数在同位次二进制位中必然一个为1一个为0
//eor的二进制位上必然有一位为1
int rightone = eor ^ (~eor+1);//提取eor二进制位里最右边的1,其余二进制位全部变为0
int onlyone = 0;
for(int cur:arr)
{
if((cur&rightone)==0)//给所有的数按这两个数不同的二进制位分类,只异或其中的一类
{
onlyone^=cur;
}
}//执行完循环后,这个onlyone为待求的某一个数
System.out.println(onlyone+" "+(onlyone^eor));//eor^onlyone 为待求的另外一个数。
}
-
结果:
4. 二分详解
(1)二分查找 O(logn)(在有序数组里查找某个数是否存在)
public static void BinarySoft(int[] arr,int x)
{
int min = 0,max = arr.length;
while(min<max)
{
int mid = (min+max)/2;
if(x==arr[mid])
{
System.out.println(mid);
return;
}
else if(x<arr[mid])
{
max = mid;
}
else
{
min = mid;
}
}
}
(2) 在一个有序数组中,找>=某个数最左侧的位置
public static void main(String[] args)
{
int[] arr = {2,4,4,4,6,7,7,8,8,9,9};
BinarySoft(arr,4);
}
public static void BinarySoft(int[] arr,int x)
{
int min = 0,max = arr.length;
int flag = 0;
while(min<max)
{
int mid = (min+max)/2;
if(x==arr[mid])
{
flag = mid;
if(arr[flag-1]<arr[flag])
break;
else
max = mid;
}
else if(x<arr[mid])
{
max = mid;
}
else
{
min = mid;
}
}
System.out.print(flag-1);
}
(3) 局部最小值问题