常见面试中的算法解法

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个结点。代码如下:

技术分享图片

 

以上是关于常见面试中的算法解法的主要内容,如果未能解决你的问题,请参考以下文章

剑指offer算法编程题目部分汇总(解法略)

数据结构算法,面试问题TOP10

程序模拟洗扑克牌(算法)

面试中的排序算法总结

面试中的排序算法总结

四则运算算法问题十五行代码巧解,面试笔试可救命!