常见解题方法(位运算、双指针、前缀和)

目录

      • 位运算
      • 双指针
      • 前缀和

对于自己刷题过程中遇到的一些常见简单解题方法进行了一个总结:

数组在数据结构中是线性表的一种,在算法题中常常以整数数组和字符串等形式展现,其实数组中包含有更多的数据类型,这一段主要说明整数数组的一些常见问题解法;

数组的一个特点,可以通过下标对于数据进行一个快速访问,即a[i] = xx;

位运算

本质上应该算在数学系算法的一大类,通过数组中的各个数进行一个位运算来获得最终的结果。
位运算指数转化为二进制后的一系列运算,比如与、或、非、同或、异或、左移右移等,通过这些运算达到一个高效率的算法;常见解题方法(位运算、双指针、前缀和)_第1张图片
常见的是利用它的一些特性来解决问题:比如左右移位的按位处理;异或结果的两个运算数相同为0,不同为1;
以一些例题说明:

1、leetcode29两数相除

这一题要求实现两个数相除;不允许使用除号、称号、取余;

解法:分析问题直接从结果来看需要得到除法,假设计算A/B,除法本质是数A中包含少个B;
那么一种直观的解法是采用减法循环实现,就用 A=A-B这种形式,直到无法再减;比如10/3;它可以减3次,到第三次A等于1无法再减了;总共循环了三次,所以结果为3;

接受两个参数A\B,除数与被除数
define count = 0;计数器;
while(A大于B){
        A-B,;计数器加1;
}
返回计数器;
(这里没有考虑越界情况,仅仅解释算法)

这种算法显然有待优化,优化的方式是 每次尝试去减B的倍数,尝试一次多记几次计数器;比如13/3;尝试13/(3+3+3+3)= 1;实际结果应该是这四个三相加; 不能使用乘法;所以这里可以使用左移,即3<<<4;可以直接得到结果而不用再加;因此可以用高位来慢慢向下移动直到找到结果;

		接受参数A和B;
		define 计数器
		for(i=31 to i=0){
		如果B左移 i 次的结果大于A;那么计数器等于这个值;
		}
		return 计数器

2、leetcode137只出现一次的数字
这一题是指一个数组中只有一个数出现一次,其他出现3次;求这个数,比如[2,2,1,2,3,3,3]的结果为1;

解法:以数字的二进制形式来说,对于出现三次的数字,二进制位出现的次数都是 3 的倍数。
因此,统计所有数字的各二进制位中1的出现次数,并对 3 求余,结果则为只出现一次的数字。
举个例子 比如 [1,1,1,3];每一个数的每一个二进制位都加起来然后取余3,得到的结果应该是011即3;

		      //循环32次,int有32位
		        for(int i = 0;i<32;i++){
		            int sum = 0;
		            for(遍历数组中的数n){
		                //对数组中的每一个数,每次右移 i 位在与1;即取出第i位上的值;
		                sum += (n>>i)&1;
		            }
		            //对每一二进制位上的数求和取余得到最终结果的第i位上的值;在归位;
		            sum%=3;
		            ans+=sum<

3、leetcode318求最大单词长度
给定一个字符串数组 words,找到 length(word[i]) * length

你可能感兴趣的:(java,排序算法,快速排序)