算法学习Day01

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


一、时间复杂度是什么?

该算法计算次数相加后取最高阶,无视常数,所剩下的部分

如选择排序 共需要计算n+n-1+n-2+……
等差数列计算公式可得
an²+bn+c
去除低阶与常数,剩下了n²
所以该算法的时间复杂度就是O(n²)
O()最差情况下时间复杂度
θ()平均情况下时间复杂度
Ω()最好情况下时间复杂度

二、简单排序算法

1.选择排序

基本思想:

先假定数组0号位是最小下标,循环到后边找到最小的数,之后交换位置

动图演示:

在这里插入图片描述

代码如下:


public class DemoApplication {

    public static void main(String[] args) {
        int [] arr = {1,2,4,5,6,11,5,53,24,666};
        selectsort(arr);
        for (int i : arr) {
            System.out.println(i);
        }
    }

    public static int[] selectsort(int[] arr){
        if(arr.length<2){
            return arr ;
        }

        for (int i = 0; i < arr.length-1; i++) {
            int minIndex = i;
            for (int j = i+1; j < arr.length  ; j++) {
                minIndex = arr[j]> arr[minIndex]?minIndex:j;
            }
            swap(arr,i,minIndex);
        }
        return arr;
    }
    public static int [] swap(int[] arr,int i,int j){
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;

        return arr;
    }

}

2.冒泡排序

基本思想:

两层循环,比较相邻元素,如果后者比前者大,那么交换位置,这样一轮循环结束后,最大的一个就会在最后的位置。

动图演示:

在这里插入图片描述

代码如下:

package com.example.demo;

public class maopaosort {
    public static void main(String[] args) {
        int [] arr = {1,2,4,5,6,11,5,53,24,666,12,45,55,4562,6456,243234325,343,35345,45326,54353};
        sort123(arr);
        for (int i : arr) {
            System.out.println(i);
        }
    }

    public static int [] sort123(int [] arr){
        for (int i = 0; i < arr.length ; i++) {
            for (int j = 0 ; j < arr.length ; j++) {
                if(arr[i]<arr[j]){
                    swap(arr,i,j);
                }
            }
        }

        return arr;
    }

    public static int [] swap(int[] arr,int i,int j){
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;

        return arr;
    }
}

3.插入排序

基本思想:

保证一个段内是有序的

动图演示:

在这里插入图片描述

   public static void main(String[] args) {
        int[] a = {17, 1, 24, 5, 566, 76, 456, 2366, 8632, 233};
        sort(a);
        for (int i : a) {
            System.out.println(i
            );
        }
    }

    public static void sort(int[] arr) {
        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);
            }
        }

    }

    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];
    }

三、异或运算基础知识

&: 计算时位同1取1
| :计算时只要有一个1 那就取1
~ :取反
^: 相同取0 不同取1;可以看作一种不进位的加法


四、一种更加优雅的交换两个数据的方式:异或运算

交换数据正常来说都会想到一个用中间变量承载数据,再交换的套路,如下图所示:

  public static int [] swap(int[] arr,int i,int j){
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
        return arr;
    }

但或许我们可以选择一种更加优雅的方法来解决眼前的问题:异或运算
异或运算,就是相同取0 ,不同取1,我们可以将它看作一种不进位的加法。
异或运算满足交换律和结合律,
那么可以得到 可以通过

a = a ^ b;    //此时: a = a ^ b   b = b
b = a ^ b;    //      a = a ^ b   b = a ^ b ^ b 两个b相同取0  b = a
a = a ^ b;    //      a = a ^ b ^ a  a = b  b = a;

突出一个优雅。
但需要注意的是,a和b必须占用不同的内存空间****
以后遇到这种情况不妨尝试一下吧~


五、练习题目

1)有一个整数数组,其中有一种数为奇数,其他均为偶数,请问如何取出这个奇数?
2)如果有两种奇数,其他都为偶数,要怎样取出?

第一题:全部异或即可

   int [] a = {1,1,2,3,3};

        for (int i = 0; i < a.length -1  ; i++) {

            a[i] = a[i] ^ a[i+1];

        }
        for (int i : a) {
            System.out.println(i);
        }

第二题:
首先全部异或的话,temp = a^b 因为偶数数量的全部被异或掉了。
那么因为a b还存在,所以他们一定有一位不同,不然就会得0.
我们设法取出a b钟不同的一个数,进行分类,那么全部数字会被分成:某一位为1,某一位为0的两个部分。
将两部分分别异或,其他的一定都会被消除掉,剩下的就是奇数位的数。

如何去取出最右一个不同的数:
原数据 :000001100
取反: 111110011
加一: 111110100
原数据与取反加一异或:000000100
如此得到第三位可以作为区分位。

将000000100与数组中数据与运算,同1取1,即可。

具体代码实现:


        int [] a = {1,1,2,2,3,3,4,5};
        int temp = 0;
        for (int i : a) {
            temp =  temp ^ i;
        }
        // temp = a ^ b
        int rightone = temp &(~temp + 1);  //驱护最右边的一个1
        int left = 0;
        for (int i : a) {
            if((i&rightone)==0){
                left^=i;
            }
        }

        System.out.println(left+" :" +(left^temp));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值