剑指offer之1/6

1.为类添加一个赋值运算符函数。
注意点:需要保证算法的异常安全性。

  • 返回值为引用

  • 传入参数也是类的引用,而且应该加const(引用可以防止内存的无谓消耗)

  • 应该先释放this类的私有数据内存,否则会内存泄露。
    class A:
    A& A::operator=(const A& str)
    {
    if(this==str)
    return *this; 如果两个类相等,那就不用复制了

    delect[] m_pData; ///删除原有的数据
    m_pData=new char[strlen(str.m_pData)]+1] 新分配一段内存 这里有个缺陷,new有可能因为内存不足造成分配内存失败!!!
    strcpy(m_pData,str.m_pData);///复制
    return *this;
    }

优化解法:
A& A::operator=(const A& str)
{
if(this!=str)
{
A temp(str);///定义一个临时类对象实例,和str相等
///交换temp和this里面的数据
char* ptemp=temp.m_pData;
temp.m_pData=m_pData; ////if结束后,temp.m_pData就被释放了
m_pData=ptemp;
}
return *this
}

2.数组中重复的数字
如果一个数组中没有重复的数字,那么n个数,排序后应该每个数都能对应唯一的下标,例如:
0 1 2 3 4对应数组下标应该是0 1 2 3 4。如果出现重复,那么一定会有多个数值对应一个下标。
算法步骤:
从数组第一个数开始,比较它的值与下标是否相等,相等进行下一个,不相等把这个值换到它应该出现的下标那(比如i[0]=2,那么这个数应该换到下标为2的位置)
在换的过程中,如果发现当前要换的这个值与要换到的位置上的值相等,这就是一个重复值(比如,i[0]=2,i[2]=2,2就是重复的)

第二种算法是用二分法,把数的范围不断一分为二,如果在某一般的数的个数超过了这一半的长度,那其中肯定有重复,就这样不断的缩小范围,最后找到重复的数。

3 二维数值查找
思路:从数组的右上角或者左下角入手
如果要寻找的数比右上角的数大,右上角所在行就可以删去了,如果寻找的数比右上角小,那么右上角所在列就可以删去了。不断的缩小了寻找的范围,直到找到要找的数。

4 替换空格
思路:先遍历字符串,计算出有几个空格,然后腾出相应的空间,一个空格需多加2长度(空格变%20)。使用两个指针,一个指向原始字符串的最后一格,一个指向扩充之后的数组的最后一格,把第一个指针指向的值赋给第二个指针指向的位置,如果遇到空格,第二个指针分别赋值0,2,%然后指针前移3个。

5 从尾到头打印链表
思路:使用栈或者递归 (使用递归容易造成栈溢出,谨慎使用)

扫描二维码关注公众号,回复: 13583106 查看本文章

6.重建二叉树
用前序遍历和中序遍历确定该二叉树,应该分析前序遍历和中序遍历的特点,从前序遍历中找到根节点,从中序遍历确定该根节点的左右子树。 最后用到了递归!

7 二叉树的下一个结点
思路:分析中序遍历的特点,分三种情况
如果该结点是右子结点,而且这个结点还有右字树,那下个结点是右字树的最左子节点
如果该节点是左子结点,那他的根节点就是下个结点
如果该结点是右子结点,而且这个结点没有右子树,那下个结点是找该结点的根结点,如果这个根节点是它的根节点的左子结点,那么这个根节点的根节点是下一个结点。

8 栈和队列
栈是先进后出,队列是先进先出,用两个栈就可以进行队列先进先出的操作

9 递归 斐波那契数列
单纯的递归会产生大量重复的计算,如果把之前运算的结果保存下来,能很好的提高效率。

10 旋转数组中的最小数字
找出位于数组中间的那个数,如果这个数大于数组第一个元素,说明它在第一个子序列里,我们要找的是第二个子序列的第一个元素(最小数字), 把第一个指针移到这个中间数上,如果中间数小于数组最后一个元素,说明他在第二个子序列里,把最后的指针移到当前中间的这个位置。
当第一个指针和第二个指针指向的数相同时,只能遍历查找了。。。因为判断不出中间数到底应该在哪个子序列当中了

11 矩阵中的路径
使用回溯法,注意点是当进行到一个字符,他的周围都没有路径了,那么需要退回到上一个字符,重新查找新的路径

12 机器人的运动范围
从(0,0)进入,判断是否能进入,能进入标记下该位置能进入,然后判断该点的前后左右能不能进入,直到遍历完所有的格子。

13 剪绳子
把一根长为n的绳子截一刀后,乘积可能是f(n)=f(n-i)f(i)。所以我们应该求出不同的i对应的乘积,然后从中找出最大的一个。
贪婪算法的做法是这一根绳子,我们尽可能多的截出3,如果最后剩1,那么还出一个3,用2截,因为2
2>3*1

14 二进制中1的个数
为了避免死循环,不采取二进制数右移位的方式,采取flag左移位的方式
巧办法,需要知道一个事儿:n和n-1做与操作,n的二进制数最右边的一个1会变成0,也就是说,能与n-1做几次与操作,而n不等于0,就有几个1.

猜你喜欢

转载自blog.csdn.net/weixin_39373577/article/details/89288781