数据结构与算法
P3 认识复杂度和简单排序算法
题目一 冒泡排序
异或运算
(1) 0N=N,NN=0
(2) 满足交换 律和结合律 ab=ba,(ab)c=a(bc)
位置交换:
public static void swap(int[] arr,int i,int j){
arr[i]=arr[i]^arr[j];
arr[j]=arr[i]^arr[j];
arr[i]=arr[i]^arr[j];
}
仅限arr[i] arr[j]在不同的存储空间时使用
题目二
-
数组中有一个数出现了奇数次,其他数出现了偶数次,如何得到出现了奇数次的数?
-
数组中有两个数出现了奇数次,其他数出现了偶数次,如何得到出现了奇数次的数?
1.:eor=0,eor^=arr[i] 把数组的数都异或一遍
2.:
public static void printOddTimesNum2(int[] arr){
int eor=0;
for (int i =0;i<arr.length;i++){
eor^=arr[i];
}
int rightOne=eor & (~eor+1);//提取出最右的1
int onlyOne=0;
for(int cur : arr){
if((cur & rightOne)==0){
onlyOne^=cur;
}
}
System.out.println(onlyOne+" "+(eor ^ onlyOne))
}
题目三 插入排序
时间复杂度O(N^2),额外空间复杂度O(1)
时间复杂度:按照最差情况估计算法表现
插入排序的实现:
public static void insertionSort(int[] arr){
if (arr==null || arr.length<2){
return;
}
// 0~0有序的
//0~i 想有序
for (int i=1;i<arr.length;i++){//0~i做到有序
for(int j=i-1; j>=0 && arr[j]>arr[j+1];j--){
swap(arr,j,j+1);
}
}
}
题目四 二分法的详解与扩展
!二分不一定有序
- 在一个有序数组中,找某个数是否存在
时间复杂度O(log_2 N)→O(log N)
-
在一个有序数组中,找>=某个数最左侧的位置
O(log N) 区别在于一定会二分结束
-
局部最小值问题
无序,相邻数一定不相等 局部最小:i-1 i i+1
题目六 对数器
public static void main(String[] args){ int testTime=500000; int maxSize=100; int maxValue=100; boolean succeed=true; for (int i=0;i<testTime;i++){ int[] arr1=generateRandomArray(maxSize,maxValue); int[] arr2=copyArray(arr1); insertionSort(arr1); comparator(arr2); if(!isEqual(arr1,arr2)){ //打印arr1 //打印arr2 succeed=false; break; } } }