【一周刷爆LeetCode,算法大神(左程云)耗时112天打造出算法与数据结构基础到高级全家桶教程+大厂面试真题详解】

1 认识复杂度、对数器、二分法与异或运算

评估算法优劣的核心指标是什么?

  • 时间复杂度(流程决定)
  • 额外空间复杂度(流程决定)
  • 常数项时间(实现细节决定)

何为常数时间的操作?

如果一个操作的执行时间不以具体样本量为转移,每次执行时间都是固定时间。称这样的操作为常数时间的操作。

总之,执行时间固定的操作都是常数时间的操作。

反之,执行时间不固定的操作,都不是常数时间的操作。

数组(常数操作)和列表

数组在内存空间中,是连续的区域;

列表在内存中不是连续的,而是一个指针指向下一个指针。

常数时间的操作:一个操作如果和样本的数据量没有关系,每次都是固定时间内完成的操作,叫做常数操作。比如数组的寻址操作,得到arr[i]的值,只需要起始地址+i就能算到该位置的地址,得到该位置上得值,是常数操作。而列表的寻址,就要逐个遍历,才得到list[i],这就不是常数操作。

如何确定算法流程的总操作数量与样本数量之间的表达式关系?

1,想象该算法流程所处理的数据状况,要按照最差情况来。

2,把整个流程彻底拆分为一个个基本动作,保证每个动作都是常°数时间的操作。

3,如果数据量为N,看看基本动作的数量和N是什么关系。

如何确定算法流程的时间复杂度?

当完成了表达式的建立,只要把最高阶项留下即可。低阶项都去掉,高阶项的系数也去掉。

记为:〇(忽略掉系数的高阶项)

选择排序

选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零:

先找最小,次小,次次小…如此类推,一共n轮排序,每轮排序记录次轮比较中最小元素的位置,然后交换。

冒泡排序

冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。 它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。 这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。

 

插入排序

i处与左边比较进行,如果小则进行交换,如果还比次左边小则再进行交换

额外空间复杂度

你要实现一个算法流程,在实现算法流程的过程中,你需要开辟一些空间来支持你的算法流程。

作为输入参数的空间、不算额外空间。

作为输出结果的空间,也不算额外空间。

因为这些都是必要的、和现实目标有关的。所以都不算。

但除此之外,你的流程如果还需要开辟空间才能让你的流程继续下去。这部分空间就是额外空间。如果你的流程只需要开辟有限几个变量,额外空间复杂度就是O(1)。

申请有限的变量,后面会此释放空间

最优解是什么意思?

一般情况下,认为解冲—人-..上,一定要尽可能的低,先满足了时间复杂度最低这个指标之后,

使用最少的空间的算法流程,叫这个问题的最优解。

一般说起最优解都是忽略掉常数项这个因素的,因为这个因素只决定了实现层次的优化和考虑,而和怎么解决整个问题的思想无关。

认识对数器

1,你想要测的方法a

2,实现复杂度不好但是容易实现的方法b

3,实现一个随机样本产生器

4,把方法a和方法b跑相同的随机样本,看看得到的结果是否一样

5,如果有一个随机样本使得比对结果不一致,打印样本进行人工干预,改对方法a和方法b

6,当样本数量很多时比对测试依然正确,可以确定方法a已经正确。

认识二分法

1)在一个有序数组中,找某个数是否存在

2)在一个有序数组中,找>=某个数最左侧的位置

3)在一个有序数组中,找<=某个数最右侧的位置

4)局部最小值问题

两变量交换(三种方法)

1.借助中间量交换
int temp = a;
a = b;
b = temp;
原理:类似于两杯水互换杯子,需要借助第三个杯子来实现。

2.位移运算交换(对不同地址、内存进行运算,不是直接对数值进行运算)

a = a ^ b;

b = a ^ b;

a = a ^ b;

原理:一个数对另一个数异(化成二进制数字只要两边相同就为false,不同则为true)或两次,该数不变。

a = a ^ b; 此时a的值为a ^ b

b = a ^ b; 此时的a经上面的运算变成a ^ b,所以b = a ^ b ^ b = a;

a = a ^ b; 此时的b又经上面的运算变成 a,所以a = a ^ b ^ a = b; 实现两个数的互换

3、数值相加减交换

a = a + b;

b = a - b;

a = a - b;

原理:通过先求得两数的和再进行减运算从而互换。

a = a + b; 此时a的值为10+20=30;

b = a - b; 此时的a经上面的运算变成两数的和30,所以b = 30 - 20(原先b的值) = 10(原先a的值);

a = a - b; 此时的b经上面的运算变成10,所以a = 30 - 10(原先a的值) = 20(原先b的值)从而实现两个数的互换 。

例题

1)数组中,一个数出现了奇数次,其他数出现了偶数次,要找奇数次的数
答案:将所有数都异或,最后只剩下奇数次的数。

	public static void printOddTimesNum1(int[] arr) {
		int eor=0;
        for(int i=0;i<arr.length;i++){
            eor^=arr[i];
        }
		System.out.println(eO);
	}

最后异或之后只是剩下4

(2)提取出N的右侧第一个不为0的数ANS=(N&((~N)+1))

+1:将右侧的数字转变为原来的数字

(2)数组中,2种数a,b出现了奇数次,其他数出现了偶数次,要找奇数次的数
答案:将所有数都异或,得到eor=a异或b;因为a不等于b,所以eor!=0,必造成eor有一个位上为1,那个位就能用来区分a和b。

例如找到第8位可以区分a与b值不一样,那么此位为1或者0,若b在此位为1,那么设eor`=所有第8位为1的数进行异或,因为其他有偶数个,只有b为奇数个。那么eor`=b,eor^eor`=a。

例如:a=4,b=9;随机选择第3位不为1,发现4、6、12的第3位都不为0,那么设eor`=4(所有的1、6、12异或)

另外一个奇数个常数为eor^eor`=9

//计算二进制数字中有多少个1
public static int bit1counts(int N){
        int count=0;
        //011011010000  N
        //000000010000  rightOne
        
        //011011000000  N^=rightOne

        while(N!=0){
            int rightOne=N&((~N)+1);
            count++;
            N^=rightOne;
        }
        return count;
    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ccprivacy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值