指针

剑指offer 链表中环的入口节点

南笙酒味 提交于 2020-02-07 06:52:36
1.题目 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。 来源:剑指offer 链接: https://www.nowcoder.com/practice/253d2c59ec3e4bc68da16833f79a38e4?tpId=13&tqId=11208&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking 2.我的题解 2.1 快慢追赶法 先看看在同一个环中快追慢需要的时间(快指针速度 2 ,慢指针速度 1 ,追上是指二者重合),分析一下站位: 假设二者位置重合,那么已经追上了; 假设快指针落后于慢指针一个位置,那么 1 单位时刻后快指针追上慢指针; 假设快指针落后于慢指针两个位置,那么 2 单位时刻后快指针追上慢指针; 假设快指针在慢指针前面一个位置,那么 len-1 时刻后快指针追上慢指针,其中 len 是环的长度; 一般地,如果快指针距离慢指针距离为 n (顺环方向计算距离),那么快指针追上慢指针需要 n 单位时间,因为快指针每单位时间可以追上慢指针 1 个单位距离; 显然快慢指针初始站位最大距离小于环的周长,最坏情况下为 len-1 ;该情况下快指针追上慢指针时慢指针移动了 len-1 单位距离,快指针移动了 2*len-2 单位距离;

c++中四种cast转化

梦想与她 提交于 2020-02-07 06:00:30
c++中四种cast转化 1.const_cast转化 const变量👉非const变量 •常量 指针 转化为非常量的指针,并且仍然指向原来的对象 •常量 引用 转化为非常量的引用,并且仍然指向原来的对象 (★const_cast只能改变运算对象的底层const,而对顶层const无能为力 ★const_cast不能改变表达式类型,只能改变常量属性) 1.去掉const常量const属性 const int g = 20; int h = const_cast<int >(&g); 2.去掉const引用const属性 const int g = 20; int &h = const_cast<int &>(g); 3.去掉const指针const属性 const char *g = “hello”; char *h = c onst_cast<char *>(g); 使用: 1.一个函数的参数不是const对象,并且编程者事先已经知道在这个函数中不会对参 数进行修改,但需要传递的实参却是已经定义好的const对象。为了成功调用这个函数,就需要利用到const_cast在实参传递前对其进行处理,从而使函数能够成功接收这个实参 # include <iostream> using namespace std ; void Function ( int * val ) { cout <

C++二维数组动态申请内存

谁都会走 提交于 2020-02-07 05:05:17
好久没用C++刷题了,今天早上刷了几条题,感觉很陌生了。怪我,大二下实在太颓废了,没啥作为。 今天更新个关于c++二维数组内存申请的问题,当初作为菜鸟初学指针的时候,还是在这方面有点搞不通的。今天用到了,顺便写下来,适当时候给C++初学者用用。 -----------C++二维数组动态申请内存-------------- 如果对new和delete不是很了解的话可以到这里来看看,http://www.cnblogs.com/hazir/p/new_and_delete.html 首先,我们一般需要用到数组的时候,都是直接声明,比如: 1 int array[3][3]; 但是,在某些情况下,数组的维数我们是不知道的,可能是等待用户输入维数,这时候需要用变量来指定维数了。可是,我们不能直接这样声明数组,因为C++不允许直接用变量作为维数声明,必须用常量,像这样就会报编译错误: 这时候就需要用new来动态申请数组了。我们一步一步来,申请一维数组的时候,我们可以这样写: int num = 3; int* array = new int[num]; 这段代码的意思就是,用new来申请num个int类型的空间,然后返回那段空间的首地址,再赋给array。可见array是一个int类型的指针,指向那段空间的首地址。语法和逻辑无误,正常运行。 但是,申请二维数组的时候

C++11智能指针

萝らか妹 提交于 2020-02-07 04:17:56
C++11智能指针 为什么要使用智能指针: 智能指针的作用是管理一个指针,因为存在以下这种情况:申请的空间在函数结束时忘记释放,造成内存泄漏。使用智能指针可以很大程度上的避免这个问题,因为智能指针就是一个类,当超出了类的作用域是,类会自动调用析构函数,析构函数会自动释放资源。所以智能指针的作用原理就是在函数结束时自动释放内存空间,不需要手动释放内存空间。 1.auto_ptr (c++98的方案,cpp11已经抛弃) 采用所有权模式 auto_ptr< string> p1 (new string ("I reigned lonely as a cloud.”)); auto_ptr<string> p2; p2 = p1; //auto_ptr不会报错. 此时不会报错,p2剥夺了p1的所有权,但是当程序运行时访问p1将会报错。所以auto_ptr的缺点是:存在潜在的内存崩溃问题! 2.unique_ptr(替换auto_ptr) unique_ptr实现独占式拥有或严格拥有概念, 保证同一时间内只有一个智能指针可以指向该对象 。它对于避免资源泄露(例如“以new创建对象后因为发生异常而忘记调用delete”)特别有用 采用所有权模式,还是上面那个例子 unique_ptr<string> p3 (new string ("auto")); //#4 unique_ptr

剑指offer11-20

夙愿已清 提交于 2020-02-07 04:12:26
11. 旋转数组的最小值 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。 思路:由于旋转数组的特性,尾元素肯定是小于首元素的(当不考虑重复值时)。所以,每次找中间值,如果中间值大于首元素,则中元素为前面那段,相反,则为后面那段。截止条件为s,e相差1。 其次,考虑旋转0个的情况,返回的是第一个。在其次,考虑有重复的情况。如{1,0,1,1,1},{1,1,1,0,1}都可以看成{0,1,1,1,1}的旋转,故此时使用循环依次查找。 代码: class Solution { public: int minNumberInRotateArray ( vector < int > rotateArray ) { if ( rotateArray.size ( ) == 0 ) //注意vector的长度并不是array.length return 0 ; int length = rotateArray.size ( ) ; int s = 0, e = length - 1 ; int mid = 0, min ; while ( rotateArray [

C和指针 第十一章 动态内存分配

两盒软妹~` 提交于 2020-02-07 04:00:35
声明数组时,必须指定数组长度,才可以编译,但是如果需要在运行时,指定数组的长度的话,那么就需要动态的分配内存。 C函数库stdlib.h提供了两个函数,malloc和free,分别用于执行动态内存分配和释放, 这些函数维护一个可用的内存池,当程序需要内存时,它就调用malloc从内存池中提取一块合适的内存,并向该程序返回一个指向这块内存的指针,这块内存没有以任何方式进行初始化。 如果需要初始化,可用使用calloc函数。当一块分配的内存不再使用时,程序应该调用free函数把它归还给内存池。 void *malloc(size_t size); void free(void *pointer); 当malloc申请内存失败时,返回的是NULL指针,所以需要 对malloc返回值进行检查 ,确保非NULL。而free的参数,要么是NULL,要么是malloc,calloc或者realloc返回的值。向free传入NULL,不会产生任何效果。 malloc返回的是void *类型的指针,所以有的编译器可能在使用之前,需要行类型转换。 char *sPtr; //类型转换一下 sPtr = (char *)malloc(12); strcpy(sPtr, "yangxunwu"); calloc,也是分配内存,不过在分配之前会把内存初始化为0,而malloc不会初始化 void

常见的动态内存分配错误

六月ゝ 毕业季﹏ 提交于 2020-02-07 03:53:23
在使用动态分配的内存时,常出现的错误为:对null指针进行解引用操作(*),对分配的内存进行操作时越过边界,释放并非动态分配的内存、试图释放一块动态分配的内存的一部分以及一块动态内存被释放之后被继续使用。 传递给free的指针必须是从malloc、calloc、realloc函数返回的指针,传给free函数一个指针,让它释放一块并非动态分配的内存可能导致程序立即终止或在晚些时候终止。试图释放一块动态分配的内存的一部分也可能引起类似问题。例如 pi = malloc(10 * sizeof(int)); free(pi + 5);//释放后五个 这样企图释放内存的一部分是不容许的,必须整块一起释放。但realloc函数可以缩小一块动态分配的内存,有效释放它尾部的部分内存。 注意不要访问已经被free释放掉的内存,如果对指向动态分配的内存指针进行了复制,而且这个指针的几份copy散布于程序各处,则无法保证当年使用其中一个指针时它指向的内存是不是已被另一个指针释放(野指针,应将这些指针全部指向NULL)。另外必须保证程序中所有使用这块内存的地方在这块内存被释放之前停止对它的使用。 ------------------------ 动态分配内存最常见的错误是忘记检测所请求的内存是否分配成功。可以用一下方式进行改进: #include<stdlib.h> #define malloc /

25.删除排序数组中的重复项

不打扰是莪最后的温柔 提交于 2020-02-07 03:22:27
因为给的数组是已经拍好序的,所以第一个元素就是原数组的第一个元素,接着遍历,我是从0开始遍历的,所以只要下一个元素与当前元素不同,那么就不是重复的元素,就可以放进原数组中,然后j+1,这里要注意是边界条件,即i != len(nums)-1,不然数组会逸出,代码如下: 看了下题解说着也可以叫双指针法(快慢指针)。。好像容易理解些 来源: CSDN 作者: qq_40058686 链接: https://blog.csdn.net/qq_40058686/article/details/104196491

C和指针之动态内存分配

旧街凉风 提交于 2020-02-07 03:06:26
1、为什么使用动态分配内存   当不确定需要的内存空间的大小的时候,使用动态分配内存的方式去分配一块内存,这样不会对内存进行浪费。 2、动态分配内存的函数   C函数库提供了三个动态分配内存的函数:malloc、calloc、realloc,这三个函数都能进行动态的内存分配。当这些内存不再使用时可以用free函数把这些内存归还给内存池,以达到内存释放的目的。 四个函数的函数原型如下: void *malloc(size_t size); void *calloc(size_t num_elements, size_t element_size); void realloc(void *ptr, size_t new_size); void free(void *pointer);   malloc函数的参数就是需要分配的内存字节数。如果内存池中的可用内存可以满足这个需求,malloc就会返回一个指向被分配的内存块起始位置的指针。malloc所分配的内存是一块连续的地址,并不会分开位于两块或多块不同的内存。如果内存池是空的,或者它的可用内存无法满足申请的需求,此时malloc会向操作系统请求得到更多的内存,并在这块新的内存上执行分配任务。如果操作系统无法向malloc提供更多的内存,就会导致malloc分配内存失败,此时malloc会返回一个NULL指针。因此

动态分配二维数组 C++

眉间皱痕 提交于 2020-02-07 02:25:06
动态分配二维数组 1)采用指针的指针 T** 2)指针的指针指向一片存放指针数组作为行 3)指针数组中每一个元素都指向一个元素数组作为列 例如: int main(){ int h, l; cin >> h >> l; int **ptr; //定义一个 int** 的指针 //分配空间 ptr = new int*[h]; //使其指向一片有 h 个元素的数组 每一个元素存放一个指针 for (int i = 0; i < h; ++i) ptr[i] = new int[l]; //使每一个数组指针指向一片有 l 的元素的数组 每一个元素存放一个整型变量 //赋值 for (int i = 0; i < h; ++i) for (int j = 0; j < l; ++j) cin >> ptr[i][j]; //输出 for (int i = 0; i < h; ++i){ for (int j = 0; j < l; ++j) cout << ptr[i][j] << ','; cout << endl; } //释放空间 for (int j = 0; j < l; ++j) delete[] ptr[j]; delete[] ptr; return 0; } 来源: CSDN 作者: weixin_45644911 链接: https://blog.csdn.net