面试题21. 调整数组顺序使奇数位于偶数前面
题目:
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。
思考:
由于不需要奇数和奇数之间,偶数和偶数之间有排序,因此不需要用冒泡这种双循环排序算法,这样计算量太复杂
解析:
双指针:
考虑定义双指针 ii , jj 分列数组左右两端,循环执行:
指针 ii 从左向右寻找偶数;
指针 jj 从右向左寻找奇数;
将 偶数 nums[i]nums[i] 和 奇数 nums[j]nums[j] 交换。
可始终保证: 指针 ii 左边都是奇数,指针 jj 右边都是偶数 。
判断奇偶还可以用位运算。
面试题22. 链表中倒数第k个节点
输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如,一个链表有6个节点,从头节点开始,它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个节点是值为4的节点。
思考:
需要遍历两次,第一次要知道链表的长度
第二次在指定位置返回
解析:
只遍历一次的方法:
为了实现只遍历链表一次就能找到倒数第k 个节点,我们可以定义两个指针。第一个指针从链表的头指针开始遍历向前走k-1 步,第二个指针保持不动: 从第k 步开始, 第二个捐针也开始从链表的头指针开始遍历。由于两个指针的距离保持在k- l , 当第一个( 走在前面的)指针到达链表的尾节点时, 第二个(走在后面的)指针正好指向倒数第k 个节点。
另外要注意代码的鲁棒性,也就是多考虑特殊情况
所谓的鲁棒性是指程序能够判断输入是否合乎规范要求,并对不符合要求的输入予以合理的处理。
面试宫可以找出3 种办法让这段代码崩溃。
(1)输入的pListH ead 为宅指针。由于代码会试图访问空指针指向的内存, 从而造成程序崩溃。
(2)输入的以pLi stH ead 为头节点的链表的节点总数少于k。由于在for循环中会在链表上向前走k一l 步, 仍然会由于空指针而造成程序崩溃。
(3)输入的参数k 为0 。由于k 是一个无符号整数, 那么在for 循环中k- 1 得到的将不是寸,而是4294967295 (无符号的OxFFFFFFFF ) 。因此,for 循环执行的次数远远超出我们的预计,同样也会造成程序崩溃。
剑指 Offer 30. 包含min函数的栈
min的复杂度为1是因为stack没有指定位置出栈的函数,不然还是需要遍历栈,而不能只保存当前最小的入辅助栈不然会会出现A非空但B空的情况