常见面试中的算法解法
Posted liujunj
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了常见面试中的算法解法相关的知识,希望对你有一定的参考价值。
1、替换空格
解法:如果通过直接遍历str,找到其中的空格就进行替换,这样做时间复杂度则为O(n2),那么我们得想到优化这个替换过程,我们可以先遍历str得到有多少个空格需要替换,然后从后向前进行遍历这个str进行替换。
2、从尾到头打印链表
解法一:从头遍历链表,将遍历结果依次存进一个栈中,然后再遍历这个栈,就可以得到这个链表从尾到头每个节点的值
解法二:我们采取递归,代码如下。
3、用两个栈实现队列
栈的特点是后进栈先出,队列是先进栈先出。那么如果用两个栈实习的队列的添加和删除
a->b 删除a元素,那么就将stack1的元素输出依次放入stack2,输出stack栈顶,就相当于把队列的头删除了
b->c 如果依然继续删除,那么再将stack2的栈顶弹出就可
d 插入元素,直接放进stack1就可
d->e 如果要删除元素,先判断,stack2有没有元素,如果有直接弹出栈顶就可,如果没有那么就想a->b那样操作删除元素
4、旋转数组的最小数字
解析:
用p1和p2指向数组最开始头和尾,如果p1<p2,这个数组就是有序的,如果p1>=p2,那么就找到p1、p2中间元素记为mid。如果,mid<p1,则最小元素在mid和p1之间,则让p2指向mid。反之如果mid>p1,那么最小元素在mid和p2之间,让p1指向mid。如果p2-p1=1,那么这两个最小的元素就是数组中最小的。
注意:以上解法只适合与不含重复元素的数组中,如果像{0,1,1,1,1}的两个旋转数组{1,0,1,1,1}和{1,1,1,0,1}这两个数组中,是没法进行二分查找的 因为mid和p1 p2相等,这样没法判断最小元素在mid左侧还是右侧。这种情况只有采取顺序查找。
5、二进制中1的个数
解析:把一个数减去1.在和原整数做与运算,会把该整数最右边一个1变成0,那么一个整数的二进制表示中有多少个1,就可以进行多少次这样的操作。代码如下:
public static int NumberOf1(int n){ int count=0; while(n != 0){ ++count; n = (n-1) & n; } return count; }
此题扩展:
6、在O(1)时间段删除链表结点
解题思路:删链表节点,第一时间想到就是遍历整个链表,找到删除节点的前驱,改变节点指向,删除节点,但是,这样删除单链表的某一节点,时间复杂度就是O(n),不符合要求;如果我们考虑用所要删除结点的数据来替换要删除的结点数据,并指向删除结点的下下个结点,最后把要删除的哪个结点的下一个结点删掉就完成了。
7、调整数组顺序使奇数位于偶数前面
解题思路:
我们让p1和p2指向数组开头和结尾 当p1为偶数,p2为奇数时则让两个值进行交换,如果不符合,p1往后移。p2往前移,直到p2的位置在p1前面,代码如下
public static int[] sortArr(int [] arr,int start,int end) { while (start < end) { int temp; if (arr[start] % 2 == 0 && arr[end] % 2 == 1) { temp = arr[start]; arr[start] = arr[end]; arr[end] = temp; ++start; --end; } else if (arr[start] % 2 == 1 || arr[end] % 2 == 1) { ++start; } else { --end; } } return arr; }
8、链表中倒数第K个结点
解题思路:如果我们从头开始遍历。然后找到倒数第k个,这样时间复杂度在O(n2),不是最好的解题思路,那么我们咋做到O(n)的查找呢?很简单,我们让两个指针同时遍历这个链表,这两个指针相距k个结点,当第一个指针遍历到尾结点了,那么就说明后面一个指针遍历的就是倒数第k个结点。代码如下:
以上是关于常见面试中的算法解法的主要内容,如果未能解决你的问题,请参考以下文章