1、选择排序和冒泡排序的时间复杂度(O(N^2))和数据初始状态无关,无论逆序,正序,或其他此序,操作流程相同
package learn;
public class Demo {
public static void main(String args[]){
int arr[]={9,8,7,6,5};
//selectionSort(arr);
bubbleSort(arr);
print(arr);
}
//选择排序
public static void selectionSort(int arr[]){
if(arr==null || arr.length<2)return;//数组arr不指向任何对象和长度为0/1的数组无需排序
for(int i=0;i<arr.length-1;i++){
int minIndex=i;
for(int j=i+1;j<arr.length;j++){//j=i+1<arr.length ->i<arr.length-1
if(arr[j]<arr[minIndex]){//minIndex=arr[j]<arr[minIndex]?j:minIndex
minIndex=j;
}
}
//if(min!=i)swap(arr[i],arr[minIndex]); 这样写有错,只是单纯交换了两个数的值,数组中的元素未变
//可以直接在selectionSort函数中交换arr[i],arr[minIndex]。若要用另一个函数,应把arr数组也传过去
if(i!=minIndex)swap(arr,i,minIndex);
}
}
//冒泡排序
public static void bubbleSort(int arr[]){
if(arr==null || arr.length<2)return;
for(int i=arr.length-1;i>0;i--){
for(int j=0;j<i;j++){
if(arr[j]>arr[j+1])swap(arr,j,j+1);
}
}
}
public static void swap(int arr[],int a,int b) {
// int x=arr[a];
// arr[a]=arr[b];
// arr[b]=x;
arr[a]=arr[a]^arr[b];
arr[b]=arr[a]^arr[b];
arr[a]=arr[a]^arr[b];
}
public static void print(int []arr) {
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+" ");
}
}
}
2、插入排序:
正序:O(n)
逆序:O(n^2)
public static void insertionSort(int arr[]) {
if(arr==null || arr.length<2)return;
for(int i=1;i<arr.length;i++){
for(int j=i-1;j>=0 && arr[j]>arr[j+1];j--){
swap(arr,j,j+1);
}
}
}
3、二分法:
(1)在一个有序数组中,找某个数是否存在
注意事项:位运算优先级低于加减 注意加不加括号
public static boolean exist (int[] arr,int num) {
if (arr == null || arr.length == 0) return false;
int left = 0;
int right = arr.length - 1;
while (left < right) {
int mid=left+((right-left)>>1);//mid=(left+right)/2 left+right可能超出范围 -> mid=left+(right-left)/2
//位运算比除运算快
if(arr[mid]==num){
return true;//找到即返回,无需再循环
}else if(arr[mid]>num){
right=mid-1;
}else {
left=mid+1;
}
}
//找到返回,循环结束 或者 left==right 只有一个元素了
return num==arr[left];//最后一个元素是否等于num
}
循环条件可以变一下
public static boolean exist (int[] arr,int num) {
if (arr == null || arr.length == 0) return false;
int left = 0;
int right = arr.length - 1;
while (left <= right) {
int mid=left+((right-left)>>1);
//位运算比除运算快
if(arr[mid]==num){
return true;//找到即返回,无需再循环
}else if(arr[mid]>num){
right=mid-1;
}else {
left=mid+1;
}
}
return false;//最后一个数都不等,退出循环
}
(2)在一个有序数组中,找>=某个数最左侧的位置
(3)在一个有序数组中,找<=某个数最右侧的位置
package learn;
public class Demo {
public static void main(String args[]){
int arr[]={2,2,3,3,3,4,5,5,6,6,6,6,7,7,7};
System.out.println(arr.length);
System.out.println(nearestIndex(arr,3));
}
public static int nearestIndex(int[] arr,int num) {
int left = 0;
int right = arr.length - 1;
int index=-1;//记录最左
while (left <= right) {//等号别漏了,最后一个元素也要判断是否大于等于num,它也有可能是那个最左的
int mid=left+((right-left)>>1);
if(arr[mid]>=num){
index=mid;
right=mid-1;
}else {
left=mid+1;
}
}
return index;
}
}
(4)局部最小值问题
public static int getLessIndex(int[] arr,int num) {
if(arr==null || arr.length==0)return -1;
if(arr.length==1 || arr[0]<arr[1]){
return 0;//第0位为局部最小值
}
if(arr[arr.length-1]<arr[arr.length-2]){
return arr.length-1;//最后一位为局部最小值
}
//前面都没有返回的话,说明中间有数比两边都小
int left=1;
int right = arr.length - 2;
int mid=0;
while (left <right) {
//循环条件 可以假设只有3个数 left==right 这个数在前面的比较中并未大于第一个数和第三个数 无需在循环中在比较一次 故不用取等
mid=left+((right-left)>>1);
if(arr[mid]>arr[mid-1]){
right=mid-1;
}else if(arr[mid]>arr[mid+1]){
left=mid+1;
}else {
return mid;
}
}
return left;
}
5、利用异或:
题目:一个数组中有一种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这种数
public static void findOne(int[] arr) {
int eor=0;
for(int i=0;i<arr.length;i++){
eor^=arr[i];
}
System.out.println(eor);
}
题目:一个数组中有两种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这种数
public static void findOne(int[] arr) {
int eor=0;
for(int i=0;i<arr.length;i++){
eor^=arr[i];
}
//eor==a^b;
//a!=b -> eor至少有一个1
int rightOne=eor&(~eor+1);//提取eor最右侧的1
//说明此位 要么a为0,b为1 要么a为1,b为0
int x=0;
for(int i=0;i<arr.length;i++){
if((rightOne & arr[i])!=0){//找到和eor最右侧1 同一位置为1的arr中的数
x^=arr[i];//因为arr中同一位置为1的其他数都出现偶数次,异或结果为0 故x最终值不是a 就是b
}
}
System.out.println(x+" "+(x^eor));//假设x为a,则a^a^b=b
}
题目:一个数 二进制中 1的个数
public static void countOne(int n) {
int rightOne,count=0;
while(n!=0){
rightOne=n&((~n)+1);
count++;
n^=rightOne;//n-=rightOne 正数可以 负数不行
}
System.out.println(count);
}