指针数组

剑指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,

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]。为防止重复结果,若指针移动的下一个位置上的数与上一个位置上的数字相等,继续移动一位

错题本

爷,独闯天下 提交于 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

错题集

夙愿已清 提交于 2019-12-30 01:07:11
1.函数strcmp从头至尾顺序地将其对应字符比较,遇到两个字符不等时,两个字符相减得到一个int型值,两个字符串完全相同时,则返回0。 对。我的理解产生了错误。误以为返回值的是ascii码的大小。事实上int大于0则是1,小于则是-1。 2.数组名就是一个指针常量,指向数组的首元素(或者说代表了数组的首地址)。 错。数组名是地址,不是指针常量,它的值可以赋给指针。 3.有说明语句int a[4][5];,则a[2]+3表示 A 。 A.a数组行下标为2、列下标为3的元素的地址 B.0a数组行下标为2、列下标为3的元素的值 C.a数组第2行的首地址 D.a数组第3行的首地址 a[2]表示地址。+3表示地址后移3个元素 4.语句int *p; *p=50;执行时,不会有任何错误。 错。在执行时,*P没有值。printf不出来任何值。5.对于以下结构定义,++p->str中的++加在 A。 (2分) struct { int len; char *str; } *p; A.指针str上 B.指针p上 C.str指的内容上 D.以上均不是 因为p->str是对指针str的引用。 6.在一个以 h 为头的单向链表中,p 指针指向链尾的条件是(A)。 A.p->next=h B.p->next=NULL C.p->next->next=h D.p->.data=-1 p

26,27删除数组重复项

回眸只為那壹抹淺笑 提交于 2019-12-30 00:11:24
目录 26,27删除数组重复项 题目 双指针法 题26解法 题27解法一 题27解法二 26,27删除数组重复项 题目 题目26 给定一个排序数组,你需要在 原地删除 重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。 示例: 给定数组 nums = [1,1,2], 函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。 你不需要考虑数组中超出新长度后面的元素。 题目27 给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。 示例: 给定 nums = [3,2,2,3], val = 3, 函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。 你不需要考虑数组中超出新长度后面的元素。 刚开始看完题目,不知道应该怎样去解决,为什么不创建新数组就可以“原地”删除元素,在参看力扣优秀解法之后,其实只要返回的新长度的范围内符合即可。 双指针法 题26解法 首先题目是 已经排序后 的数组,在不考虑数组中超出新长度后面的元素的前提下

错题题(已更正)

喜夏-厌秋 提交于 2019-12-29 21:30:29
1.函数strcmp从头至尾顺序地将其对应字符比较,遇到两个字符不等时,两个字符相减得到一个int型值,两个字符串完全相同时,则返回0。 对。我的理解产生了错误。误以为返回值的是ascii码的大小。事实上int大于0则是1,小于则是-1。 2.数组名就是一个指针常量,指向数组的首元素(或者说代表了数组的首地址)。 错。数组名是地址,不是指针常量,它的值可以赋给指针。 3.有说明语句int a[4][5];,则a[2]+3表示 A 。 A.a数组行下标为2、列下标为3的元素的地址 B.0a数组行下标为2、列下标为3的元素的值 C.a数组第2行的首地址 D.a数组第3行的首地址 a[2]表示地址。+3表示地址后移3个元素。 4.语句int *p; *p=50;执行时,不会有任何错误。 错。在执行时,*P没有值。printf不出来任何值。 5.对于以下结构定义,++p->str中的++加在 A。 (2分) struct { int len; char *str; } *p; A.指针str上 B.指针p上 C.str指的内容上 D.以上均不是 因为p->str是对指针str的引用。 6.在一个以 h 为头的单向链表中,p 指针指向链尾的条件是(A)。 A.p->next=h B.p->next=NULL C.p->next->next=h D.p->.data=-1 p

【c】函数指针数组

谁说胖子不能爱 提交于 2019-12-29 13:11:54
部分转自: https://www.cnblogs.com/zmm1996/p/11752882.html 1.函数指针的概念 如果在程序中定义了一个函数,那么在编译时系统就会为这个函数代码分配一段存储空间,这段存储空间的首地址称为这个函数的地址。而且函数名表示的就是这个地址。既然是地址我们就可以定义一个指针变量来存放,这个指针变量就叫作函数指针变量,简称函数指针。 函数指针的定义方式为: 函数返回值类型 (* 指针变量名) (函数参数列表); 例如下面语句就定义了一个指向函数的指针变量 p。首先它是一个指针变量,所以要有一个“*”,即(*p);其次前面的 int 表示这个指针变量可以指向返回值类型为 int 型的函数;后面括号中的两个 int 表示这个指针变量可以指向有两个参数且都是 int 型的函数。所以合起来这个语句的意思就是:定义了一个指针变量 p,该指针变量可以指向返回值类型为 int 型,且有两个整型参数的函数。p 的类型为 int(*)(int,int)。 int(*p)(int, int); 2.函数指针用法 demo1: # include <stdio.h> int Max(int, int); //函数声明 int main(void) { int(*p)(int, int); //定义一个函数指针 int a, b, c; p = Max; /

数据结构:链表讲解

拈花ヽ惹草 提交于 2019-12-28 15:12:11
数据结构:链表讲解 一、缓存淘汰策略: 缓存的大小有限,当缓存被用满时,哪些数据应该被清理出去?哪些数据应该保留?这就需要缓存淘汰策略来决定。 简单理解: 就是当缓存被用满时清理数据的优先顺序 。 先进先出策略 FIFO(First In, First Out) 最少使用策略 LFU(Least Frequently Used) 最近最少使用策略 LRU(Least Recently Used) 以上策略举个栗子: 假如,你买了很多书,但有一天发现,书太多了,太占书房空间了,打算丢掉一些书籍; 丢到刚买的书:先进先出策略 丢到买完一直都没有读过的书:最少使用策略 丢到最近刚买的书,但是一直都没怎么读过:最近最少使用策略 二、数组与链表的区别: 1.底层存储的结构区别: 我们可以从 底层的存储结构 来看。数组需要一块 连续的内存空间 来存储,对内存的要求比较高。 如果我们申请一个 100MB 大小的数组,当内存中没有连续的、足够大的存储空间时,即便内存的剩余总可用空间大于 100MB,仍然会申请失败。 链表恰恰相反,它并 不需要一块连续的内存空间 ,它通过 指针 将一组零散的内存块串联起来使用,其中,我们把内存块称为链表的 结点 。 为了将所有的结点串起来,每个链表的结点除了存储数据之外,还需要记录链上的 下一个结点的地址 。结点地址的指针叫作 后继指针 next 。

归并排序就这么简单

旧街凉风 提交于 2019-12-28 04:05:47
归并排序就这么简单 从前面已经讲解了冒泡排序、选择排序、插入排序,快速排序了,本章主要讲解的是 归并排序 ,希望大家看完能够理解并手写出归并排序快速排序的代码,然后就通过面试了!如果我写得有错误的地方也请大家在评论下指出。 归并排序的介绍 来源百度百科: 归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用 分治法 (Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。 若将两个有序表合并成一个有序表,称为二路归并。 过程描述: 归并过程为:比较a[i]和b[j]的大小,若a[i]≤b[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素b[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。 原理: 归并操作的工作原理如下: 第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列 第二步:设定两个指针

两数之和(two sum)问题通用解法(map法和双指针)

岁酱吖の 提交于 2019-12-27 20:33:27
文章目录 1. [LeetCode01:two sum](https://leetcode.com/problems/two-sum/) 题意 思路1:map法 代码1: 思路2:双指针解法 代码2 小结 2. [LintCode607. Two Sum III - Data structure design](https://www.lintcode.com/problem/two-sum-iii-data-structure-design/my-submissions) 题意 思路 代码 3. 167. [Two Sum II - Input array is sorted](https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/) 题意 思路 代码 4. LintCode587.Two Sum - Unique pairs 题意 思路 代码 5. [LeetCode15. 3Sum](https://leetcode.com/problems/3sum/) 题意 思路 代码 6. [LintCode-382. Triangle Count](https://www.lintcode.com/problem/triangle-count/description) 题意 思路 代码 7.