面试中变相考算法复杂度

一:题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点。

链表结点与函数的定义例如以下:

struct ListNode
{
    int    m_nValue;
	ListNode* m_pNext;
};

void delete_note(ListNode *head,ListNode *current)
{
	// 空的
	if(head == null || current==null)
	{
		return;
	}
	else if(current->m_pNext != null)
	{// 非结尾
		ListNode *tmp = current->m_pNext;
		current->m_nValue = tmp->m_nValue;
		current->m_pNext = tmp->m_pNext;
		delete tmp;
		tmp = null;
	}
	else if(head == current)
	{// 仅仅有一个节点
		delete current;
		current = null;
		head = null;
	}
	else
	{// 尾节点,不是一个哦
		ListNode *tmp = head;
		while(tmp->m_pNext != current)
			tmp = current->m_pNext;
		tmp->m_pNext = null;
		delete current;
		current = null;
	}
}

分析:假设待删除节点为最后一个节点,则不能依照以上思路,没有办法,仅仅能依照常规方法遍历,时间复杂度为O(n),是不是不符合题目要求呢?可能非常多人在这就会怀疑

自己的思考,从而放弃这样的思路,最后可能放弃这道题,这就是这道面试题有意思的地方。虽看简单,可是考察了大家的分析推断能力,是否拥有强大的心理,充分自信。事实上

我们分析一下,仍然是满足题目要求的。假设删除节点为前面的n-1个节点。则时间复杂度为O(1),仅仅有删除节点为最后一个时,时间复杂度才为O(n),所以平均的时间复杂度

为:(O(1) * (n-1) + O(n))/n = O(1);仍然为O(1)

单向链表中删除一个结点,最常规的方法是从头到尾扫描一遍找到结点,然后删除结点。对于给定的是值得结点,没有办法仅仅能从头到尾扫描一个一个对照值得大小,假设链表

中存在。则删除结点。

本题给出的是一个结点的指针,我们无需扫描就能够得到结点的指针。在这个过程中。仅仅要把当前结点(p)的next结点(q)的值赋给当前结点。把q的

next结点连接到p的next域删,接下来删除结点q就满足题目的要求了。

可是这个题目中存在很多陷阱:首先是边界条件的考虑。然后是删除结点的位置,表头,表尾,和中间,不同的地方删除时处理不一样。

二:给定一个数组a[N],我们希望构造数组b[N],当中b[i]=a[0]*a[1]*...*a[N-1]/a[i]。

在构造过程:

1、不同意使用除法;

2、要求O(1)空间复杂度和O(n)时间复杂度。

3、除遍历计数器与a[N] b[N]外,不可使用新的变量(包含栈暂时变量、对空间和全局静态变量等);

void makeArray(int a[],int b[],int len)
{
    int i,j;
    b[0] = 1;    

    for(i=1;i<len;i++)
    {
        b[i] = b[i-1]*a[i-1];   //累乘a[0]*a[1]...a[i-1]
    }    

    b[0] = a[len-1];
    for(j=len-2;j>0;j--)
    {
        b[j] *= b[0];
        b[0] *= a[j];
    }
} 

学习心得

1  对于这样的带要求的(要求苛刻的)问题,就要求我们不能应用常规的方法来思考它。

2  这样的题,一般有一些特点,里面的技巧性非常强。当然也比較easy发现,从递推公式中能够看出一些端倪;

3  你用常规的方法书写时 再加上 从递推公式中能够看出一些端倪 应该不难看出它的解法

4  平时一定要多多练习。在自己高速地写完一个算法题后,想一想有没有更优的方法,哪怕仅仅有一点点代码优化;

5 代码优化,也是在面试的时候面试官,在你写完代码后,最爱问的一个问题。

时间: 2024-10-14 13:55:53

面试中变相考算法复杂度的相关文章

面试中变相靠算法复杂度

一:题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点.链表结点与函数的定义如下: struct ListNode { int m_nValue; ListNode* m_pNext; }; void delete_note(ListNode *head,ListNode *current) { // 空的 if(head == null || current==null) { return; } else if(current->m_pNext != null) {

巨人大哥谈Java面试中常考的信息安全方面知识(MD5)

巨人大哥谈Java面试中常考的信息安全方面知识(MD5) Java MD5 加密算法介绍以及使用 MD5 算法的介绍 特点 1.压缩性:任意长度的数据,算出的MD5值长度都是固定的. 2.容易计算:从原数据计算出MD5值很容易. 3.抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别. 4.强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的. 用途 1.可以用于加密用户密码 2.可以用于应用安装包的一致性验证 MD5 的简单

面试中的排序算法总结(转)

转自http://www.codeceo.com/article/10-sort-algorithm-interview.html 前言 查找和排序算法是算法的入门知识,其经典思想可以用于很多算法当中.因为其实现代码较短,应用较常见.所以在面试中经常会问到排序算法及其相关的问题.但万变不离其宗,只要熟悉了思想,灵活运用也不是难事.一般在面试中最常考的是快速排序和归并排序,并且经常有面试官要求现场写出这两种排序的代码.对这两种排序的代码一定要信手拈来才行.还有插入排序.冒泡排序.堆排序.基数排序.

面试中的排序算法总结

来源:http://www.cnblogs.com/wxisme/p/5243631.html 前言 查找和排序算法是算法的入门知识,其经典思想可以用于很多算法当中.因为其实现代码较短,应用较常见.所以在面试中经常会问到排序算法及其相关的问题.但万变不离其宗,只要熟悉了思想,灵活运用也不是难事.一般在面试中最常考的是快速排序和归并排序,并且经常有面试官要求现场写出这两种排序的代码.对这两种排序的代码一定要信手拈来才行.还有插入排序.冒泡排序.堆排序.基数排序.桶排序等.面试官对于这些排序可能会要

iOS面试中常见的算法题目

一.前言 这里是在iOS求职中自己遇到的算法题,希望对大家有所帮助.不定期更新.如果大家想在线运行代码调试,可以将代码拷贝到这里.然后进行调试.下面就是常见的算法题目. 二.正文 1.就n的阶乘. 思路:这里面用递归实现 #include <stdio.h> int getNJ(int n) { if (n==1 || n==0) { return 1; } return n*getNJ(n-1); } int main() { printf("%d",getNJ(10))

面试中常见的算法之Java中的递归

1.方法定义中调用方法本身的现象2.递归注意实现 1) 要有出口,否则就是死递归 2) 次数不能太多,否则就内存溢出 3) 构造方法不能递归使用3.递归解决问题的思想和图解: 分解和合并[先分解后合并] 1. 常见的斐波那契数列 1,1,2,3,5,8,13,21,...特征: 从第三个数开始,每个数是前两个数的和. int count = 0; private int getFibo(int i) { if (i == 1 || i == 2) { count = count+1; Syste

快速排序(面试中常考)

package com.atguigu.array.sort; /** * 快速排序 * 通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分关键字小, * 则分别对这两部分继续进行排序,直到整个序列有序. * @author shkstart * 2018-12-17 */public class QuickSort { private static void swap(int[] data, int i, int j) { int temp = data[i]; d

面试大总结之一:Java搞定面试中的链表题目

链表是面试中常考的,本文参考了其它一些文章,加上小编的自己总结,基本每个算法都测试并优化过. 算法大全(1)单链表 中还有一些链表题目,将来也会整理进来. * REFS: * http://blog.csdn.net/fightforyourdream/article/details/16353519 * http://blog.csdn.net/luckyxiaoqiang/article/details/7393134 轻松搞定面试中的链表题目 * http://www.cnblogs.co

Java面试题中常考的容易混淆的知识点区别

以下是我收集的Java编程里各种区别,供Java学习爱好者参考,这些区别都是每次Java面试中常考的,大家好好掌握,如有失误请留言指出.想要获取Java详细全套学习资料请到上海尚学堂官网获取. 1.HashMap和Hashtable的区别. HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable. HashMap允许将null作为一个entry的key