LeetCode---6.RestEasy

1.题目思路
1. 292. Nim Game
关键词:求余
思路:这个根据两个人可以报的数,枚举所有情况发现。
不管第一个人报什么,第二个人总能报到4.
那么如果能被4整除,第二个人可确保赢。
如果不能被4整除,第一个人将其余数报了,
这样第一个人相当于能整除情况得第一个人,可确保赢。


2. 371. Sum of Two Integers
关键词:移位
思路:分别计算进位与非进位。
①通过异或计算非进位位。
②通过相与然后左移,计算纯进位位。
然后不断递归,递归结束条件可以有2种。
(1)如果进位位与非进位位的1处于不重复的位置,直接相或即可。
这个判断条件是①和②相或的结果等于它们相异或的结果。
(2)将b看做进位位,当进位位等于0的时候即可。


3. 349. Intersection of Two Arrays
思路:
(1)对较小的vector建立哈希set,然后遍历另一个vector查找。
如果找到放到结果set里面,最后将结果set转换为vector返回。
(2)使用双指针,先排序,移动数值小的那个的下标,
如果相等的时候,就检查结果vector里面当前的,或者是否为空,插入。


4. 242. Valid Anagram
思路:
(1)遍历第一个string,将其放入一个26长度的数组中。
遍历第二个string,将该数组减一,如果有一项变为-1,即为假。
复杂度O(N)
(2)对两个string排序,然后直接看是否相等。
复杂度O(NlogN)
扩展:
①如果不是小写字母,可能是宽字符怎么办?
在(1)的思路上不放入数组,放入哈希map即可。


5. 350. Intersection of Two Arrays II
思路:完全类似于349,
(1)因为要求返回所有相同的,所以不能使用set,我们使用map
在遍历第一个的时候,统计次数。
在遍历第二个的时候,每找到一个就将次数-1。
其余一样
(2)使用双指针则更简单一点,只需要判断它们相等的时候进行插入即可。


6. 191. Number of 1 Bits
思路:每次与1相与求得最后一位,然后右移即可。


7. 70. Climbing Stairs
思路:这一题,最重要的是找清楚爬梯子的规律。
将其分解为等价的子问题。
假设n层,如果先走1步,那么剩下n-1层
如果先走2步,那么剩下n-2层。
这不就是斐波那契数列吗!
所以写一个迭代的菲波那切数列即可。
int a = 1, b = 2;
while(n > 1){
int tmp = b;
b = a + b;
a = tmp;
--n;
}


8. 198.House Robber
思路:这就是一道动态规划。
还是将原问题分解为相似的子问题。
由于不能抢劫相邻的两间,所以抢第n个的最大收益
等于max(抢n-2的最大收益+n的收益, 抢n-1的最大收益)
int a = nums[0], b = max(nums[0], nums[1]);
int n = nums.size();
for(int i = 2; i < nums.size(); ++i){
       int tmp = b;
       b = max(b, a + nums[i]);
       a = tmp;
}


9. 342.Power of Four
思考:
这里再简单回顾一下关于Power of Two的解法
(1)不停除二
(2)找到2^32 - 1以下最大的整数,然后看其对n求余是否为0
(3)取对数看是否是一个整数(这里要用到换底公式)
(4)观察发现,其实2的power只有首位为1,其余为0.
而将其减一那么久所有都为1,这个时候讲n &(n-1)肯定是0
思路:
(1)这里还是可以不停除以4
(2)由于4不是质数,所以不能采用4的最大那个对当前这个求余。
但是我们可以将判断4的,转换为判断2的。
然后再将4从2中区分出来。
首先2的power首位为1,其余为0,那么4的肯定也是这样。
只是4的power的1只能出现在0,2,4.。。。这些位
所以我们只要与上(0x55555555) <==> 1010101010101010101010101010101
看是否等于其本身,就能将4的power从2的power里面区分出来。
return num > 0 && !(num & (num - 1)) && (num & 0x55555555) == num;


10. 232.Implement Queue using Stacks
思考:
回顾用queue实现栈
(1)每次push的时候,就先将所有元素搞到tmp,然后入队新元素,
再将老元素从tmp入回来。
(2)使用q1,q2
q2专门维护栈顶元素。每次新来的元素放进q2.将以前的放入q1
每次top,如果q2不为空返回即可。如果为空就q1返回干自己,
然后将最后一个元素给q2.
pop就先调用top,然后出掉即可。
思路:
(1)引入一个tmp栈。
每次push的时候,先将之前的元素移除,在入栈新元素,再入栈老元素。
(2)方法(1)的编程简单,但是复杂度太高,每次push都要O(N)的操作。
使用old和new两个栈。
入栈入new
出栈检查old,如果old没有值将new的放过去,如果old有值直接出old即可。
这是一种均摊时间复杂度的思想。


11. 36.Valid Sudoku
思路:
(1)将行、列、方抽出来进行判断。
但是这样在抽方的时候十分困难,需要4重for循环。
(2)对每一个元素,判断它在行、列、方中是否出现过。
这样一次判断3个,且只需要2重循环遍历万元素即可。


12. 374.Guess Number Higher or Lower
思路:这是一道简单的二分查找。
第一个难点是边界情况。范围是1-n,不断取中间数最终可能取到1,
但是无法取到n,所以可以先就验证n。
第二个难点是,如何计算中间值,因为可能产生溢出的情况。
不能直接相加再除以2.
①mid = left + (right - left) / 2;
②mid = left / 2.0 + right / 2.0
注意如果分开除,一定要使用除以浮点数,本来是9.2-->9,
变为3.6和5.6-->8就坑爹了。


13. 299.Bulls and Cows
思路:
这道题的关键是要搞清楚,无论是bull还是cow都要占用secret的名额。
比如secret是"6618" guess是"6766"
其中第一个6是bull,但是后面两个6在secret只能有1个对应
所以是1bull1cow而不是1bull2cow
(1)两次遍历
第一次统计secret中各个数字出现的次数,以及bull数
第二次遍历guess,对不是bull的判定,如果是cow,要对数量减一。
(2)一次遍历
这个在是bull的时候,bull+1.然后边统计边判定。
比如如果是在secret中出现就将其-1,如果是guess出现就将其+1
如果在secret中出现了大于0的,cow++
如果是guess中出现了小于0的,cow++


14. 225.Implement Stack using Queues
思路:用queue实现栈没有太大的优化。
(1)每次push的时候,都将原本的所有元素入另一个队。
将新元素入队,使得新元素再队头。
将其他元素再入回来。
(2)用一个队列来维护,栈顶元素。
push的时候,放入栈顶队,将原来的元素放入另一个队。
top的时候,如果栈顶队有元素直接返回,如果没有需要到另一个队里面
自循环一次,在出队出出来。
pop的时候先top,然后再pop
注意:这里的两种方法唯一的区别就是,
一个将复杂度放在了push,一个将复杂度放在了pop
如果一个栈的push和pop操作差不多,那么两种方法代价是一样的。


15. 205.Isomorphic Strings
思路:
(1)用一个数统计,现在已经出现的char的种类。
然后将其存入新出现的种类的映射中,然后再判断,如果不同就是false
(2)不需要使用哈希表,使用int m[256]
也不需要专门用一个数去计数,使用i来存放,看上次出现的位置是否一样。


16. 290.Word Pattern
思路:这一题和205完全类似。
对于字母用数组,对于string用哈希表即可。


17. 190.Reverse Bits
思路:
将无符号数先转换为二进制,然后再将二进制转换为无符号。
注意转换的时候本身就是从末位开始转,所以再转换过来的时候自动完成了reverse bits


18. 303.Range Sum Query - Immutable
思路:
第一步先将到第N位的和计算出来,放进一个数组。
第二步每次求的时候,用sum[j] - sum[i - 1]即可。


19. 155.Min Stack
思路:
(1)用一个值来专门记录min或者max,
然后再每次push的时候判断
最耗时的是如果出栈出了min或max的值的那个元素,需要全部弹出再进一次。
(2)使用两个栈来实现,一个栈存放元素,另一个栈专门记录是否是最小值。
push的时候,如果比top小就再push进最小值栈。
pop的时候,如果pop了最小值栈栈顶元素,把最小值栈也出出去。

20. 278.First Bad Version
思路:这一题是二分查找的变种。
利用递归,递归结束条件是后比前多1.
递归过程是,如果是bad version向左。否则,向右。


2.题型总结


3.思考
1.将数值类型转换为字符串可以利用函数
#include<string>
std::to_string()
这个函数是C++11引入的,但是目前GCC 4.9.2还没有支持。


2.对字符进行统计个数可以不用哈希表,直接用int m[256] = {0}即可。

这样比哈希表效率高很多。 若干倍速度的提升!


3.求平均的时候防溢出

mid = (left + right) / 2;

改为mid = left + (left + right) / 2;

或者mid = left / 2.0 + right / 2.0;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值