指针

剑指Offer

穿精又带淫゛_ 提交于 2020-02-27 17:26:41
题目:给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。 思路: 设置快慢指针,都从链表头出发, 快指针每次 走两步 ,慢指针一次 走一步 ,假如有环, 一定相遇于环中某点(结论1)。接着让两个指针分别从相遇点和链表头出发,两者都改为每次 走一步 ,最终相遇于环入口(结论2)。以下是两个结论证明: 两个结论: 1、设置快慢指针,假如有环,他们最后一定相遇。 2、两个指针分别从链表头和相遇点继续出发,每次走一步,最后一定相遇与环入口。 证明结论1 :设置快慢指针fast和low,fast每次走两步,low每次走一步。假如有环,两者一定会相遇(因为low一旦进环,可看作fast在后面追赶low的过程,每次两者都接近一步,最后一定能追上)。 证明结论2: 设: 链表头到环入口长度为-- a 环入口到相遇点长度为-- b 相遇点到环入口长度为-- c 则:相遇时 快指针路程=a+(b+c)k+b ,k>=1 其中b+c为环的长度,k为绕环的圈数(k>=1,即最少一圈,不能是0圈,不然和慢指针走的一样长,矛盾)。 慢指针路程=a+b 快指针走的路程是慢指针的两倍,所以: (a+b)*2=a+(b+c)k+b 化简可得: a=(k-1)(b+c)+c 这个式子的意思是: 链表头到环入口的距离=相遇点到环入口的距离+(k-1)圈环长度 。其中k>=1,所以 k-1>=0

c++函数指针

£可爱£侵袭症+ 提交于 2020-02-27 15:29:27
静态成员函数的地址可用普通函数指针储存,而普通成员函数地址需要用 类成员函数指针来储存。 class base { static int func1 ( ) ; int func2 ( ) ; } ; int ( * pf1 ) ( ) = & base :: func1 ; //普通的函数指针 int ( base :: * pf2 ) ( ) = & base :: func2 ; //成员函数指针 静态成员函数不可以调用类的非静态成员。静态成员函数不含this指针,而普通成员函数默认携带this指针参数。 把指针函数当作 形参 传递给某些具有一定通用功能的模块。并封装成接口来提高代码的灵活性和后期维护的便捷性。 另外,有些地方必须使用函数函数指针才能完成给定的任务,如linux系统中的异步信号中断处理,当发生某一触发信号时,需要调用相应的处理函数,此时需要使用函数指针来实现。 void ( * signal ( int signum , void ( * handler ) ( int ) ) ) ( int ) ; 来源: CSDN 作者: xiaoxiao落木 链接: https://blog.csdn.net/qq_28133013/article/details/104536253

「算法」环形链表 & 环形链表 II

徘徊边缘 提交于 2020-02-27 14:03:04
00141 环形链表 题目描述 给定一个链表,判断链表中是否有环。 实例 1: 输入:head = [3,2,0,-4], pos = 1 输出:true 解释:链表中有一个环,其尾部连接到第二个节点。 示例 2: 输入:head = [1,2], pos = 0 输出:true 解释:链表中有一个环,其尾部连接到第一个节点。 示例 3: 输入:head = [1], pos = -1 输出:false 解释:链表中没有环。 力扣地址 https://leetcode.com/problems/linked-list-cycle https://leetcode-cn.com/problems/linked-list-cycle 解题报告 哈希表 本题解由微信公众号 小猿刷题 提供, 错误之处, 欢迎指正. 通过检查一个结点此前是否被访问过来判断链表是否为环形链表。常用的方法是使用哈希表. /** * 微信公众号"小猿刷题" * Definition for singly-linked list. * class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { public boolean

结构指针

ぐ巨炮叔叔 提交于 2020-02-27 13:14:03
1.结构作为函数参数 int numberOfDays(struct date d) 整个结构可以作为参数的值传入函数 这时候是在函数内新建一个结构变量,并复制调用这个结构的值 也可以返回一个结构 这与数组完全不同 struct date { int month ; int day ; int year ; } ; bool isLeap ( struct date d ) ; //判断这一天所在的年份是不是闰年 #include <stdbool.h> int numberOfDays ( struct date d ) ; int main ( int argc , char const * argv ) { struct date today , tomorrow ; printf ( "Enter today's date(mm dd yyyy):" ) ; scanf ( "%i %i %i" , & today . month , & today . day , & today . year ) ; if ( today . day != numberOfDays ( today ) ) { tomorrow . day = today . day + 1 ; tomorrow . month = today . month ; tomorrow . year =

C++中指针和引用的区别

和自甴很熟 提交于 2020-02-27 10:27:17
1.指针和引用的定义和性质区别: (1)指针:指针是一个变量,只不过这个变量存储的是一个地址,指向内存的一个存储单元;而引用跟原来 的变量实质上是同一个东西,只不过是原变量的一个别名而已。如: int a=1;int *p=&a; int a=1;int &b=a; 上面定义了一个整形变量和一个指针变量p,该指针变量指向a的存储单元,即p的值是a存储单元的地址。 而下面2句定义了一个整形变量a和这个整形a的引用b,事实上a和b是同一个东西,在内存占有同一个存储单 元。 (2)引用不可以为空,当被创建的时候,必须初始化,而指针可以是空值,可以在任何时候被初始化。 (3)可以有const指针,但是没有const引用; (4)指针可以有多级,但是引用只能是一级(int **p;合法 而 int &&a是不合法的) (5)指针的值可以为空,但是引用的值不能为NULL,并且引用在定义的时候必须初始化; (6)指针的值在初始化后可以改变,即指向其它的存储单元,而引用在进行初始化后就不会再改变了。 (7)”sizeof引用”得到的是所指向的变量(对象)的大小,而”sizeof指针”得到的是指针本身的大小; (8)指针和引用的自增(++)运算意义不一样; (9)如果返回动态内存分配的对象或者内存,必须使用指针,引用可能引起内存泄漏; 来源: https://www.cnblogs.com

成员变量是指针的注意点

耗尽温柔 提交于 2020-02-27 07:10:17
若使用成员拷贝,则指针指向同一块区域,不行,目的是指向拷贝一份相同存储空间区域过来 若使用赋值运算符,则需要判断传入的参数不是自己,若是自己则指针指向的那份待拷贝空间没了,即使保留一段时间,但是再次拷贝出空间时候,值会消失,接下来没了拷贝的值 来源: CSDN 作者: Tine Chan 链接: https://blog.csdn.net/chanleoo/article/details/104457850

AC自动机

感情迁移 提交于 2020-02-27 05:10:59
首先简要介绍一下AC自动机:Aho-Corasick automation,该算法在1975年产生于贝尔实验室,是著名的多模匹配算法之一。一个常见的例子就是给出n个单词,再给出一段包含m个字符的文章,让你找出有多少个单词在文章里出现过。要搞懂AC自动机,先得有模式树(字典树)Trie和KMP模式匹配算法的基础知识。KMP算法是单模式串的字符匹配算法,AC自动机是多模式串的字符匹配算法。 AC自动机和字典树的关系比较大,所以先来简单的了解下字典树Trie。 字典树又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。 简而言之:字典树就是像平时使用的字典一样的,我们把所有的单词编排入一个字典里面,当我们查找单词的时候,我们首先看单词首字母,进入首字母所再的树枝,然后看第二个字母,再进入相应的树枝,假如该单词再字典树中存在,那么我们只用花费单词长度的时间查询到这个单词。 AC自动机算法分为3步:构造一棵Trie树,构造失败指针和模式匹配过程。 AC自动机关键点一:字典树的构建过程: 字典树的构建过程是这样的,当要插入许多单词的时候,我们要从前往后遍历整个字符串

数组和指针的区别

情到浓时终转凉″ 提交于 2020-02-27 03:42:56
数组和指针的区别 1.数组和数组第一个元素 # include <stdio.h> void main ( ) { int arr [ ] = { 5 , 8 , 6 , 9 , 3 , 4 , 1 , 7 , 2 , 0 } ; //arr = { 2,5,1 };数组名是常量,不可被赋值,这么操作报错 int * p = arr ; printf ( "数组的地址:%p\n" , arr ) ; printf ( "数组第一个元素的地址:%p\n" , & arr [ 0 ] ) ; printf ( "p的值:%p\n" , p ) ; } 返回的结果 数组的地址: 000000457811F A88 数组第一个元素的地址: 000000457811F A88 p的值: 000000457811F A88 上述表明数组其实就是数组第一个元素的位置,arr就是一个地址,所以arr复制给p没问题 2.数组的遍历 void main ( ) { int arr [ ] = { 5 , 8 , 6 , 9 , 3 , 4 , 1 , 7 , 2 , 0 } ; int * p = arr ; printf ( "int类型指针大小%d\n" , sizeof ( int * ) ) ; //输出8 printf ( "p指针大小%d\n" , sizeof ( p ) ) ; /