剑指offer第二章

博客介绍了C++和C#编程语言的基本概念,如C++中不同类型的sizeof结果、虚函数定义,以及C++和C#成员访问权限默认设置差异。还详细讲解了C++中数组的定义,包括静态和动态数组,分析了数组与指针的关系,并给出数组重复数字查找的面试题及多种解法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2.2 编程语言

    1)C++:基本概念的理解。

        a、空类型的实例sizeof占用的1字节空间

        b、空类型的实例中,没有任何成员变量和成员函数,只有构造函数和析构函数,求sizeof得到结果为1字节。因为构造函数和析构函数只需要知道函数的地址即可,这些函数的地址只与类型相关,而与类型的实例无关。

        c、在32位机器上,对一个指针求sizeof结果为4字节,64为机器求sizeof指针结果Wie8。 int占4字节,char占1个字节。float 4字节,double 8字节。

        d、虚函数的定义

     2)C#:

之前做项目的时候,用过一段时间的C#,可惜技艺不精,忘得差不多了。

C++中,没有标明成员函数或成员变量的访问权限级别,在struct中,默认为public,而在class中默认为private

C#中,没有标明成员函数或成员变量的访问权限级别,在struct和class均默为private。

2.3 数据结构:数组、字符串、链表、树、栈和队列以及高级一点的图结构!

2.3.1 数组是最简单的数据结构。

1 在C++中定义数组主要分为,静态数组和动态数组两种类型。 

静态数组: int arra[100]={0}  定义一个长度为100的数组,初始值全赋值为0.    int array1[] = { 0,1,2,3,4};  这样虽然在[] 中没有指定大小,编译器默认大小为5 。 int array1[];这样是不允许的。另外,数组赋初值格式为 大括号{}  不能用中括号 []

动态数组: 有时候,数组的大小我们事先是不知道的,也就是说是一个参数,那么就只能使用动态数组的了,表达方式为:

int *arr=new int[length]  length可以作为参数进行传递。这个表达方式最后要释放的  delete[] arr;

另一种实现动态数组的方式是采用STL中的vector  定义为vector<int >v;本质也是采用动态数组的方式进行构建的  可以直接v.push_back(元素名称)。

内部实现是动态数组,即为了避免浪费,每次先开一个小空间,然后往数组中添加数据,当数据的数目大于数组的容量时,再分配一块更加大的空间,每次扩充容量都是前一次的两倍,在把原来的数据拷贝到新的数组汇总,在释放原来的内存,,可以避免浪费,但是缺点也是显而易见的,影响时间性能。

2 数组与指针的关系(P38)

1)数组的名字也是一个指针,该指针指向数组的第一个元素,C++没有记录指针的大小 int data [] ={1,2,3,4} int *data2 =data; 就可以这样定义

2)当数组作为函数的参数进行传递时,数组就自动退化为同类型的指针(比如int型的数组,退化为int型的指针,对指针求sizeof结果均为4(32为系统)),

举例: int Getsize(int data[])

{ return sizeof(data);} 输出为 4

实战:面试题3 

1)找出数组中重复的数字:空

小知识点:data==nullptr 数组为、

题目一:找出数组中重复的数字:

1)暴力求解:两个for循环,时间上暴力,不需要额外的空间

2)排序: 排列一个n 数组,需要时间复杂度 O(nlogN),再遍历一遍数组

3)哈希表:每遍历一个元素把其加入到哈希表中 (Python中用字典dir实现) 时间复杂度为O(n),空间复杂度O(n)

C++中,用map实现已经写出来了,效果不错:https://blog.youkuaiyun.com/baidu_30594023/article/details/81914551 自己的博客

map.find() //map中find的返回值:引用具有指定键的元素的位置的迭代器,如果找不到具有键的匹配项,则引用映射中 (map::end()) 最后一个元素后面的位置。返回值必须用iter迭代器来承接 ,判断的时候也只能用 if(iter!= map.end()) 代表,找到了key相同的元素

Python实现:dir的思路: 和C++相类似:

def FindNum(data):

dir1={} #字典用的是大括号{}表示

for i in range(len(data)):

if data[i] in dir1:

return True

else:

dir1[data[i]]=1

return False

虽然这不是本题的最优解,但是这样用map哈希表的思想去解决问题的思路和代码实现是必须要会的

4)题目中给出的是按照下标位置进行判断,不断的进行交换,类似于data[i]是多少,就把这个数放在以data[i]为下标的数组中。(这样会带来初始值为多少的问题,可以这样解决:初始数组全为0,当放入时,该数组的位置加1,这样还能统计出每个数字出现的次数。)这样很明显,局限性很大:前提是长度为n的数组,所有数字均在0~n-1范围内。否则这个方法是不能使用的。一定有重复。

题目二:不修改数字的顺序找出重复的数字

很明显,上面的方法中,只有方法4)是不可用的。

这种方法: 通过统计在一定范围内出现的次数的方法是无法保证找出所有的重复的数字的这道题是有bug的吗,{ 2, 8, 5, 4, 3, 2, 6,7 }; 是计算不出重复的数字的,原因在于,找某一个范围内的数字出现次数,可能有的值没有出现,有的出现了多次,这样就不能保证有效性。 例如 {1,1,1,1} 在1-4 范围内出现了4次,但是显然不能说没有重复数字。

这是一个bug,总体来讲,是不能使用的。

面试题4:思路比较简单,代码也清晰易懂,就不多说了。

今天就到此为止,明天见~

2.3.2 字符串

  知识点:

1 为了节省内存,C++把常量字符串单独放在一个内存区域。当几个指针赋值给相同的常量字符串时,他们实际上会指向相同的内存地址,但是用常量内存初始化数组,情况就会有所不同。

char str[]="hello" char str2="hello" ,str1!=str2    因为str1与str2的内存地址是不同的 

char *str3="hello" char *str4="hello"    *str3=*str4  因为str3与str4的指向是相同的 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值