剑指offer
03:数组中的重复数字,如果可以修改原数组,可以把遍历过的数字取成负值或者其他原来不可能出现的数字,表示此处已被遍历。
04:二维数组的查找:不是遇到有序数组就可以用二分很好的解决出来,像这种有序的矩形数组可以观察矩形的四个角有什么特点,是否可以从角着手遍历排除。
05:替换空格:for(char c:s)并不能遍历字符串
11: 旋转数组的最小数字:旋转数组一般都是和数组的头或者尾比较进行二分(经确定,只有和尾部比较才有特点,比尾大的一定是左半部分,小的一定是右半部分,相等的话,舍弃尾部,right--),注意尾部是right是实时变化的,并不是固定nums.length-1;不是所有的二分题都要舍弃mid(left=mid+1;right=mid-1),像本题舍弃右边时,mid不能被舍弃,应使right=mid。
12: 矩阵中的路径:矩阵的回溯有上下左右四种选择,不一定要在每个回调函数前后包裹着回溯逻辑,可以改变回溯的i,j。在整体代码外包裹回溯代码。
14: 剪绳子I:可以使用动态规划,定义dp的含义,如果定义dp[n]表示绳子剪成n段的值,那么子问题之间没有状态转移方程,如果定义成长度为n的绳子的最大值,那么有状态转移方程。
14: 剪绳子II:ab%c != a%cb%c,所以如果像上题一样用动态规划,无法在过程中取余,只能使用bigint。换种解法:大于4时,n中分成越多3越好。
15:二进制中1的个数:无符号右移操作是>>>,有符号位移操作是>>1,有符号位移如果是负数,会在高位补1
16:数值的整数次方:降低时间复杂度的办法是 x^y = (x*x)^(y/2)
31: 栈:栈的入栈和出栈方法分别是 push,pop
32:队列:队列的入队和出队方法分别是add,poll
33: 分层打印二叉树:queue.size()就等于当前层的个数
34:之字形打印二叉树:使用Deque deque = new ArrayList<>();dequeue是double ended queue,双端队列,可以使用addFirst()的方法在队列头部加元素,也可以用addLast()在队列尾部加元素。最后使用new ArrayList<>(deque)转成arraylist。
II25:链表的两数相加:
方法一:反转链表
方法二:如果不允许修改原链表,则可以使用栈来模拟反转链表