指针

剑指offer 旋转数组的最小数字

微笑、不失礼 提交于 2020-01-01 02:46:55
题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个 非减排序 的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。 思路:首先理解数组的旋转定义,可以发现旋转数组可以划分为两个非减排序的子数组,而最小元素在两个子数组的分界处。 (1)我们用两个指针分别指向数组的第一个元素和最后一个元素,根据旋转数组定义,我们知道第一个元素应该是大于等于最后一个元素的。 (2)找到数组的中间元素;   如果中间元素位于前面的递增子数组,那么它应该大于等于第一个指针指向的元素,此时最小元素应该在中间元素的后面。我们把第一个指针指向中间元素。   如果中间元素位于后面的递增子数组,那么它应该小于等于第二个指针指向的元素,此时最小元素应该在中间元素的前面,我们把第二个指针指向中间元素。 可知,第一个指针始终指向前面递增子数组的元素,第二个指针总是指向后面递增子数组的元素。它们最终会相邻,而第二个指针会指向最小元素。这就是循环结束的条件。 除此,我们还需要考虑一些特殊情况: 1、数组未旋转,即旋转后的数组和原数组一致,那么第一个元素是最小元素。 2、考虑有重复元素的情况:{1, 0, 1 , 1, 1}, {1, 1, 1 , 0,

单链表及循环链表已知问题整理

ε祈祈猫儿з 提交于 2019-12-31 22:05:58
1. 如何快速查找到一个单链表的中间位置 方法:通过快慢指针来查找中间位置。设置两个指针,快指针和慢指针,慢指针每次移动一次,快指针每次移动两次。当快指针出现null,则到达链表末尾。此时慢指针的数据就是中间值。 2. 一个单链表,输出此链表的倒数第k各节点。 方法一:遍历单链表,求出链表长度N。(求出K点的位置P)N-K=P,再次从头开始遍历至P点。 方法二: 1.定义两个指针p1,p2分别指向链表的头部。 2.P1前进值K点,则p1,p2相距K点。 3.p1,p2开始同时前进,每次前进一个节点。 4.当p1到达末尾,p2所在的位置就是K点的位置。 3. 怎么判断链表是否是循环链表 方法一:通过快慢指针来检测链表是否是循环链表。设置两个指针,快指针和慢指针,慢指针每次移动一次,快指针每次移动两次,如果快指针追赶上慢指针,则为循环链表,否则不是循环链表。 方法二:借助hasmap判断是否经历过此点。 4. 求有环单链表的环长 在环上相遇后,记录第一次相遇点为Pos,之后指针slow继续每次走1步,fast每次走2步。在下次相遇的时候fast比slow正好又多走了一圈,也就是多走的距离等于环长。   设从第一次相遇到第二次相遇,设slow走了len步,则fast走了2 len步,相遇时多走了一圈:     环长=2 len-len。 5.求有环单链表的环连接点位置

函数指针做形参

最后都变了- 提交于 2019-12-31 12:40:15
cpp] view plain copy print? #include <stdio.h> void func(int* p) { printf("*p = %d/n", *p); printf("&p = %p/n", &p); } int main(int argc, char *argv[]) { int *a = new int(10); printf("*a = %d/n", *a); printf("&a = %p/n", &a); func(a); return 0; } 编译:g++ -g -Wall test1.cpp 运行:./a.out 输出: *a = 10 &a = 0xbfd4447c *p = 10 &p = 0xbfd44460 我们看到输出,a 指向的地址的值和p 指向的地址里的值是一样的,都是10 。然而,对于指针a 和p 来说,它们自身的地址是不一样的,所以我们看到,函数func 复制了指针a 给p ,它们的值一样,但有不同的地址,是不同的指针。 我们再进一步: [cpp] view plain copy print? #include <stdio.h> void func(int* p) { printf("*p = %d/n", *p); printf("&p = %p/n", &p); printf("&*p = %p/n", &*p

C语言错题集

社会主义新天地 提交于 2019-12-31 02:10:20
一、选择题 (1).若有定义:int *p[4];则标识符p是()。 A: 是一个指向整型变量的指针 B: 是一个指针数组名 C: 是一个指针,它指向一个含有四个整型元素的一维数组 D: 定义不合法 标准答案:B, 解析:p是一个具有4个元素的指针数组,每一个元素是一个int型指针 (2).下面判断正确的是 ()。 A: char *a=“china”;等价于char *a; a=“china”; B: char str[10]={“china”};等价于char str[10];str[]={“china”}; C: char *s=”china”;等价于char *s; s=”china”; D: char c[4]=”abc”,d[4]=”abc”;等价于char c[4]=d[4]=”abc”; 标准答案:A, 解析:A:指针变量可以在定义时初始化(赋初值),也可以在定义之后再初始化。 B:字符串数组必须在定义的时候就初始化,否则就要从键盘上输入给它初始化。 C:指针变量只能存放地址,不是把字符串赋给s,只是把”china”的第一个字符的地址赋给指针变量s。在C语言中只有字符变量,没有字符串变量。所以应该是等价于char *s; s=”china”。 D:字符数组之间不可以直接互相这样赋值。 (3).若有说明:int i, j=2,*p=&i;, 则能完成i

Remove Duplicates from Sorted List I II -- leetcode

我只是一个虾纸丫 提交于 2019-12-31 02:00:42
(1) Remove Duplicates from Sorted List I 题目意思: 删除重复节点,但是保留第一个重复的结点. For example, Given 1->2->3->3->4->4->5, return 1->2->3->4->5. Given 1->1->1->2->3, return 1->2->3. 思路: (1) 定义两个指针,一个指向当前结点,一个指向其前驱 (2) 判断当前结点是否与其前驱结点值一样,一样则向后移动当前结点, 直到不在重复为止. (3)此时当前结点可能为空, 删除重复结点后,前一个指针的next设为null即可; (4)如果移动后,当前结点不为空,需要将前一个指针的next指向p(无论上一次p是否移动过, 没有移动即没有重复结点的情况下,前一个结点本来就是其前继结点,如果移动,那么p指向的正好是第一个不同于其前继的结点) 代码: class Solution { public: ListNode* deleteDuplicates(ListNode* head) { if (head == NULL) return NULL; ListNode *pre = head;//前驱结点 ListNode *p = head -> next; while (p != NULL){ while (p != NULL && pre ->

C语言错题集

ε祈祈猫儿з 提交于 2019-12-30 23:16:03
指针 1.char *s=“C Language”;表示s是一个指向字符串的指针变量,把字符串的首地址赋予s。 (1分) T 2.C 语言是一种具有某些低级语言特征的高级语言。 (1分) T 3.文件指针用于指向文件,文件只有被打开后才有对应的文件指针。 (1分) T 4.在C语言中,逗号既可以作为运算符,也可以作为分隔符。 (1分) T 5.变量被定义后 , 它的作用域和寿命就被确定了 , 并且不可改变。 (1分) T 6.字符串在内存中的起始地址称为字符串的指针,可以定义一个字符指针变量指向一个字符串。 (1分) T 7.设变量定义为 int a[2]={1,3}, p=&a[0]+1;,则 p的值是( )。(2分) A.2 B.3 C.4 D.&a[0]+1 B &a[0]+1是地址的增加 8.以下结构类型可用来构造链表的是()。 (2分) A.struct aa{ int a;int * b;}; B.struct bb{ int a;bb * b;}; C.struct cc{ int * a;cc b;}; D.struct dd{ int * a;aa b;}; B 9.若有函数max(a,b),为了让函数指针变量p指向函数max,正确的赋值方式是( )。 (2分) p=max; *p=max; p=max(a,b); *p=max(a,b); A 在本题中

Leetcode刷题笔记——n-sum问题

假如想象 提交于 2019-12-30 22:44:02
2Sum: 题目描述: 给定一个整型数组nums,一个target,从数组中找出a、b,使得a+b=target;并且假定数组中只有一对满足条件的a、b 原始思路: 用两个for循环遍历数组,找出结果,时间复杂度为O(n 2 ) 优化思路: 使用hash表,建立HashMap<Integer, Integer> map,键值对为<nums[i],i>。遍历数组nums,对每个数nums[i],查询hash表中是否有key等于target-nums[i]的记录,若有,则找到;否则,将num[i]和下标i存入hash表。因为hash表的查找时间复杂度可以看作是O(1),所以算法时间复杂度就降为O(n)了。 3Sum: 题目描述: 给定一个整型数组nums,从数组中找出所有不重复的[a,b,c],使得a+b+c=0 原始思路: 3个for循环,但是超时了 优化思路: 使用双指针。首先将数组排序(防止重复),然后遍历数组,在每个位置i,设置双指针,左指针指向位置i+1,右指针指向位置nums.length-1,计算三个位置数之和,若等于0,则将三数位置下标加入结果集,左指针右移,右指针左移;若大于0,则右指针左移;若小于0,则左指针右移,直到左右指针相遇。遍历完数组,找到所有符合条件的[a,b,c]。为防止重复结果,若指针移动的下一个位置上的数与上一个位置上的数字相等,继续移动一位

#15 3Sum

限于喜欢 提交于 2019-12-30 22:40:40
正确解法: 在排序之后,用for loop确定最小的数,然后让剩下两个指针在最小数的基础上,分列两边,向中间靠拢。 关于重复的考虑:对于最小的指针,只需要保证最小的指针不一样即可。对于另外两个指针,只有在成功塞进结果列的情况下才需要考虑,这时候,只要把重复去掉就好了。 时间复杂度O(n2)。 我的问题: O(n3)次的复杂度:既然我这么用了,其实排序并没有带给我积极的意义。排序本身的作用是利用这一串数字的排列,来减小时间复杂度。 对于重复的数字,实际有两个bound来决定要不要继续找数字。 有新的数存在 在a的基础假设上,以a为动力,来移动指针 → 用我的方法,存在一个问题,就是当这一串数字的末尾全是重复数字的时候,我无法 预知在后面是否还有新的数字存在。所以,其实从两边向中间的方法就可以解决这个问 题,我只要check左边的指针永远小于右指针就可以了。 修正后的代码:(只作为参考,记录下来) class Solution { public List<List<Integer>> threeSum(int[] nums) { List<List<Integer>> result = new ArrayList<>(); if(nums.length < 3){ return result; } Arrays.sort(nums); if(nums[0] > 0 || nums

关于快慢指针的若干应用详解

∥☆過路亽.° 提交于 2019-12-30 22:37:31
一.问题来源   昨晚看微博,发现于梁斌penny,他在说现在的面试制度考不出来真功夫,也就是基本功,面试题千篇一律的算法,看过会,不看就不会。期间提到了快慢指针求中位数。   查资料时我发现,这其实是计算机系统原理里的知识点。 二.快慢指针概念   快慢指针中的快慢指的是移动的步长,即每次向前移动速度的快慢。例如可以让快指针每次沿链表向前移动2,慢指针每次向前移动1次。 三.快慢指针的应用 3.1 判断单链表是否为循环链表   对于初学者来说,要解决这个问题,最可能采取的方法就是使用两个循环。当外层循环步进一个节点时,内层循环就遍历外层循环节点之后的所有节点,然后比较内外循环的两个节点。若有节点地址相等,则表明该单链表有循环,反之则不存在循环。这种方法无疑效率比较低。   今天给大家介绍一个经典的方法,通过快慢指针来检查单链表是否存在循环。其思路很简单,大家可以想一下上体育课长跑的情景。当同学们绕着操场跑步的时候,速度快的同学会遥遥领先,最后甚至会超越其它同学一圈乃至n圈——这是绕圈跑。那么如果不是绕圈跑呢?速度快的同学则会一直领先直到终点,不会再次碰到后面的速度慢同学——不考虑地球是圆的这种情况。   快慢指针的设计思想也是这样。快指针每次步进多个节点——这个视情况而定,慢指针每次只步进一个节点。那么如果该链表存在循环的话,快指针一定会再次碰到慢指针,反之则不存在循环。

错题本

爷,独闯天下 提交于 2019-12-30 04:29:38
错题本 1、数组 1-5 对于已正确定义的二维数组a, *(a[i]+j)与a[i][j]的含义相同。 (2分) T (F) 评测结果:答案错误(0 分) 1-7 数组名就是一个指针常量,指向数组的首元素(或者说代表了数组的首地址)。 (2分) (T) F 评测结果:答案错误(0 分) 1-10 假设有定义如下: int array[10]; 则该语句定义了一个数组array。其中array的类型是整型指针(即: int *)。 (2分) (T ) F 评测结果:答案错误(0 分) 来源: CSDN 作者: no1304870436 链接: https://blog.csdn.net/no1304870436/article/details/103757198