刷题疑惑3

1、等值距离和(340周赛B):有时间复杂度的要求,采用前缀和策略,保存在一个前缀和数组中,序列是从左往右递增的,所以可以将其分为左侧和右侧分开计算,模板题;同有序数组中差绝对值之和;

既然数组是非递减有序的,那么a[i]左边的元素一定不大于它本身,右边的元素一定不小于它本身;
我们先计算出i位置(包含i)的前缀和pre[i];
a[i]与它左侧的所有元素绝对值差的和,等于i * a[i] - pre[i-1];;
a[i]与它右侧的所有元素绝对值差的和,等于pre[a.length-1] - pre[i] - (a.length-1-i) * nums[i];

2、判断是否是质数:采用平方根方法,1不是质数,所以从2开始计算;

bool isPrime(int num){
    if(num <= 1) return false;
    for(int i = 2;i*i <= num; ++i){
        if(num % i == 0) return false;
    }
    return true;
}

3、最小化数对的最大差值二分思想+贪心;周赛常考的知识点;看到最大值最小的问题就想二分方法;先排序,相邻的元素差值一定最小,所以转化为最多选几个数对使得最大差值不超过x,x就是我们要枚举的元素;如果我们选了大于等于p个数对,那么该答案就通过检验;多写写类似题目,若将 排序后相邻元素的差值记录下来,该题还可以转化为  打家劫舍;

4、跳跃游戏Ⅱ:动规做时间复杂度高;贪心好一些;起始时只能跳一次,将能跳到的范围内的值挨个枚举,更新最大值;

5、网格图中最少访问的格子数(340周赛D):mn个set数组,行set存放列,列set存放行,使用bfs遍历当前节点的每一个大于行或列的下标,即 [i, i + grid[i ][j ] ]范围内的下标;更新dp数组;

6、最少翻转次数:灵神的解法:BFS + 平衡树;首先是对于区间内的下标 i,由于是中心对称翻转,边界[L, R],翻转后是 L+R - i;其翻转后的下标是公差为2 的等差数列;其次是左右边界影响会有一些下标不会翻转到,分为边界处的,不在边界处的;得出一个下标i,能达到的范围;用两颗平衡树维护下标不在banned中的奇数下标和偶数下标,之后入队p元素,bfs搜索;

7、最低成本联通所有城市:知识点:最小生成树,方法有Kruskal(克鲁斯卡尔)和Prim(普里姆)算法最小生成树(Kruskal(克鲁斯卡尔)和Prim(普里姆))算法动画演示_哔哩哔哩_bilibili

8、课程表:思路是邻接表,vector<unordered_set<int>>course(n); 拓扑排序思想,无环图,检测是否有环;bfs(入度为0的点先入队) 、dfs;使用辅助数组存储访问过的节点;

9、将二叉搜索树变平衡:将二叉树转变为数组存储起来,寻找数组中间的分割点,递归左区间和右区间,证明略;终止递归条件就是left > right;

10、零钱兑换Ⅱ:组合问题,外层循环是物品,内层循环是背包;再理解理解

11、零钱兑换Ⅰ:取最小数目;

12、字符串相乘:考虑十进制相乘,num1的第 i 位 和 num2的第 j 位相乘;会在结果的[i +j ,i + j + 1]位;每一次都要考虑低位的进位;看的评论区的答案;多写写;

13、分割数组以得到最大和:动规, 代表以当前下标结尾的最大值;前k个元素就是这k个元素最大的值与元素个数的乘积;k个以后,有k种情况;往前回退j 个元素( 1< j < k),求最大值;

14、解码方法:动规,先判定第一个字符是否是 0,若是直接返回0;分两种情况,一个字符一个字符走; 还是两个字符走;判定边界就是前一个字符为1;或者为2且当前字符小于6;

15、统计各位数字都不同的数字个数:考虑首位不为0,第一位能选 1~9,9个,第二位能选 0~9 中处了第一位以外的 9 个,第三位 8 个。。以此类推;考虑首位为 0,相当于 n-1 的情况,在前面已经计算过了,两者相加;

16、接雨水:二刷方法一,动规做,两个数组存储左右边界,三次遍历; 一刷方法三,双指针, 空间复杂度优化为O(1),时间复杂度为O(log N);

17、使数组严格递增:困难,dfs做,选或不选,把a[0] - a[i] 替换成递增数组,且最后一个数小于pre,所需最小操作数,dfs(i, pre);还有一个变形题,这道题类似于 最长递增子序列

18、滑动子数组的美丽值( 342周赛3 ):方法一是使用两个multiset,一个放前x个元素,一个放前k个剩下的元素,维持总共k个不变;方法二是用一个取值范围大小的数组,来存nums数组中K个区间中每个元素的个数,下标表示对应的元素,值为元素的个数;增加偏移量,防止数组越界;因为取值范围是-50 ~ 50;

19、打家劫舍Ⅱ:第一家和最后一家挨着,所以两个dp数组,一个从第一个开始倒数第二结束,一个从第二个开始最后一个结束;两个dp数组取最大值;可以提取一个函数计算指定范围内的能达到的最大值; 空间复杂度可以达到O(1),仅使用两个变量交替变量,达到最优;

20、为运算表达式设计优先级:对运算符进行分割,递归求解结果,每次遇到运算符时,将字符串分为左侧和右侧两部分,递归求解两部分的结果;之后将其两两结合;得到本次运算的一部分结果;

21、回溯算法:子集问题分为 不包含重复元素的问题(easy 子集问题Ⅰ) 与 包含重复元素(medium 子集问题Ⅱ) ,包含去重问题,去重条件的判断;

排列问题:全排列问题(灵茶山的算法比较优化,先建立数组,然后填充),

组合问题:组合Ⅰ、组合Ⅱ、组合Ⅲ、回溯问题,有无重复元素;

22、背包问题

0-1背包,一维滚动数组:

二维dp数组:dp[ i][ j] 表示从下标为【0-i】的物品来任意取,放进容量为 j 的背包;价值总和最大是多少;初始化定义视情况而定;遍历顺序可以是先背包再物品,也可以是先物品再背包(一般),正序遍历;

简化为一维滚动dp数组:dp[ j]表示容量为j 的背包的最大价值;初始化一般为0;遍历顺序是先物品再容量,不能颠倒,否则背包里只放入一个物品??,并且背包的遍历顺序是倒序进行的;这是因为正序的话,会覆盖之前的数据,通俗讲就是 保证物品 i 只会被放入一次;

完全背包:一维数组;如果求组合数就是外层for循环遍历物品,内层for遍历背包。如果求排列数就是外层for遍历背包,内层for循环遍历物品。

遍历顺序是先物品后背包;并且背包的遍历顺序是从小到大;保证物品可以被多次添加;遍历顺序也可以是先背包后物品;

对于排列的问题,例题:组合Ⅳ,先背包后物品;

23、最长字符串链:考虑记忆化 动态规划,使用 unordered_map 记录,考虑将字符串数组排序之后从最小长度的字符串开始,以当前字符为结尾的字符,遍历去掉任意一个字符的字符串作为前串,更新当前的最大值;

24、前缀和后缀搜索:方法一是暴利方法,直接遍历 每一个字符,保存每一个可能的前后缀组合,使用unordered_map保存起来;方法二是  使用前缀树进行保存,两个字典树,并且每个节点保存一个该单词在数组中的下标值,一个字典树保存单词正序的方法,一个字典树保存单词倒序的方法,然后判断给的前后缀是否存在,若存在的话,将该节点的数组中下标值记录下来,比较两个数组中的下标值,从后往前比较,若相等就返回;

25、找出叠涂元素(343周赛B):可以用数组记录 每行有几列已经被涂色,当元素涂色的时候,就将值加一,当==列数的时候,就返回此时的下标;(思路很重要);

26、前往目标的最小代价(343周赛C):dijkstra算法应用,可以不用建图,直接找最小值,因为是个完全图;

这儿有个知识点:map的键值可以是pair,因为没有hash函数,但是unordered_map 的键值为pair的时候,会报错,需要自己实现hash函数;

27、字典序最小的美丽字符串(343周赛D):长度为2 的回文串,就是两个相邻的相同字符,长度为3的回文串,就是下标之差为2的两个相同字符,所以当且仅当任何一个字符与它前两个字符都不同;使字典序最小的且比s大的,从最后一个字符开始,让其变大,变化后还不能与前两个字符相同;若没有,则接着向前查找;那么最终,只需让修改的字符后面的字符都变为最小的字符就行,且不与前两个字符相同;(思路很巧妙);

28、摘水果:二分查找的方法好理解,相当于模拟;进阶就是滑动窗口的做法,代码量少,不好理解;

29、连续子数组的最大和:方法一是 动规求解,定义两个变量,加上当前的值 是否小于当前值 小于则直接赋值为当前值,否则加上 当前值;方法二是 :线段树求解,可以在O(logN)时间复杂度内,求出任意区间的最大子数组和;

30、下一个排列:二刷,由思路,但是没写出来; 找出一个左边的「较小数」与一个右边的「较大数」交换 ;交换后,右边的数是逆序的,按照升序排列即可;官解的reverse 自己实现的话可以利用双指针,swap;

31、最长递增子序列的个数:由最长递增子序列基础上进阶,新增一个计数容器,表示当前的组合数;若dp[i] == dp[j] + 1,则正好是组合数相加;若dp[i] < dp[j] + 1,则是直接赋值;

32、区域和-数组可修改树状数组的 单改区查操作;

33、距离相等的条形码、重构字符串:这两个题基本一样,计数+排序的方法,两次遍历,或者使用偶数、奇数两个下标进行填入,奇数下标填入小于等于于一半的字符,并+=2;偶数下标填入多于一半的字符并+=2;

34、统计完全连通分量的数量:完全连通分量:每两个点之间都有一条边,因此顶点与边的关系有:( (vertex - 1) * vertex) / 2 = edges ;在建图的时候可以建立双向的边,这样,每条边会被计数两次;

判断 edges == (vertex - 1)* vertex,若相等则为一个完全连通分量;

35、按列翻转得到最大值等行数:方法很巧妙,找到本质相同的行,为了方便统计本质相同的行的数量,我们让由 1 开头的行全部翻转,翻转后行内元素相同的行即为本质相同的行,求相同行中的最大值;

36、负二进制转化:除基取余法,基数为-2,余数要取绝对值,商要先减去这个余数,在除以-2,最后倒序输出;

37、负二进制数相加:先转整数会溢出;使用模拟法:进位转化为 {-1, 0 , 1},相加的结果为{ -1,0,1,2,3};x == -1时,进位为1,本位也为1,所以会多出x为3的情况,也按x==2处理;x==2时,进位为-1,本位为x-2;最后,要注意最后位为3的时候,进位为-1,-1之后还要产生1的进位,因此最多会多出两位;

38、活字印刷:组合数组的问题;含有重复元素;

39、一个整数的惩罚数(346周赛C)子集型回溯问题;将字符串分成多个子集,子集相加求和得出;

40、蓄水:枚举蓄水次数;然后枚举在当前的蓄水操作下,需要的升级操作;

41、根到叶路径上的不足节点:dfs,递归经典问题,判断根到叶子节点的路径和是否小于limit,是返回false,否则true;左右子节点为false,则置为空;

42、受标签影响的最大值:两个数组,一个数组存储值,一个存储标签,从大到小的排序,可以另起一个数组,存储下标,利用iota赋值,之后按照value数组大小进行排序;

43、大样本统计:计算中位数的方法,官解方法这个方法很独特;利用两个边界条件判断:left = (总数+1) /2;right = (总数+2)/2;这两个边界适应于奇偶总数都可以;当已经遍历的数目满足这两个条件时就加上值;

44、二进制矩阵中最短路径:bfs经典问题;多刷几遍;八个方向上统计;利用辅助数组判断是否访问过;若访问过则直接跳过,已经保证为最短了;

45、对于acm模式,写输入的时候,对于下面这种情况,可以先写入 getline 获取整行数据,而后使用 istringstream 初始化,最后在分别输入到对应的对象;

       

 46、收集巧克力(349周赛C)枚举旋转的次数;这个思想可以借鉴一下;因为旋转n-1次之后,每个值都取到了最小值;所以结果肯定在n-1次旋转之内;在当前旋转的次数内, 每个值取它能取到最小值;

 47、树节点的第k个祖先:倍增思路,先预处理每个节点的父节点、爷爷节点;按2的倍数来记录;dp[x][i]记为节点x的第2i个祖先节点;例如,pa[x][0]=parent[x],即父节点;先枚举 i  再枚举 x;

  对于k,从小到大的找到二进制表示的所有1;往上跳 2步,逐步更新;

48、拆分成最多数目的正偶数之和:从小到大依次将偶数入栈,最终结果若不为0,则将最后一个数和剩下的余数进行相加入栈;

50、过桥的时间:模拟题,四种状态,左右各两种,循环的条件就是还有箱子或者右侧有人在等待或者右侧有人在工作;按照优先级进行顺序操作;

51、树中距离之和换根DP,典型题;看灵茶山的解法,好理解;

52、数组的最大美丽值:(354周赛B):滑窗的思想,很巧妙,当时没想出来;;;多看看;二重循环滑窗比 二分思想快;

53、354周赛C、D都看看零茶山的解法;

54、模拟 行走机器人:对于四个方向的走向,利用一个四行二列的数组,表示四个方向上走一步;正北方向初始化为1,向右旋转就是加1,向左旋转就减1;小于0就加上4,结果对4取余;

55、环形子数组的最大和分类讨论,第一种情况就是没有跨越边界的普通最大子数组和;第二种情况就是跨越边界,枚举分割点,取最大前缀和最大后缀相加;两者取最大;

56、满足不等式的最大值:这个题是使用双端队列的经典题型;使用双端队列存储{x, y - x};题目可以简化为求 x2+ y2 + y1 - x1的最大值,满足x2 - x1 <= k;依次遍历每一个点; 队列不为空,则先弹出不满足 队首的x小于当前元素的x在k之内的队首元素,然后更新最大值; 最后将队尾小于当前元素的y-x的值弹出,将此元素入队尾;

 57、合并后数组中的最大元素:(355周赛B):脑筋急转弯题,应该从后往前遍历,若前一个元素(正序)小于当前元素就让当前元素加前一个元素;否则,令当前结果等于当前元素;

 58、数组整数操作:(牛客周赛4C):先记录加减值结果sum,以及最小值mini,之后对于数组中每一个值,判断其加上最小值是否是大于等于0,若大于0,则加上加减结果值;反之,则加上加减结果减去最小值;

59、找出最安全路径(357周赛C):bfs,多源最短路模型 + 瓶颈路模型 + 二分答案;很好的题;

60、任意子数组和的绝对值的最大值:两种方法,最大正值dp和最小负值dp,或者前缀和,学习两个新函数partial_sum函数,minmax_element函数;

61、美团笔试(0902):第二个题,就很呆,想了好多方法,还是没做出来,递归真不能做吗?(遗留问题,难受),最后还是看的别人的解法,用动态规划做的;

 


使数组所有元素变成1的最少操作次数:

posted @ 2023-04-10 15:26  QianFa01  阅读(47)  评论(0)    收藏  举报