Likou刷题(31,29,25,56,59,60,61,66,69,71,73,88,89)

1 : 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。

思路:两重循环就可

2. 给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。请你将两个数相加,并以相同形式返回一个表示和的链表。

 思路:创建一个新的头节点,两链表相加之和放在新的节点中,并链在此头结点之后,形成新的代表和的输出链表。每次相加,都要确定和是否大于10---dec代表相加之和,对10取余放在新列表对应节点中,对10取整,加在下一次两链表之和中;即,只要两链表下一节点不全为空,或下一节点为空,但当前节点所加大于10,都需要创建新的节点。

3. 将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:

 之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"

官方

 my:

思路:先创建一个二维数组(大小可根据给定的S的长度及规定的行数确定)。当在第一列时,挨个取出S中元素放到第一列中的每行,列数+1。然后判断当前列数+1是否=numsrow;若不等于,行数从倒数第二循环到1处,放一个s[k]在每行中,行数-=1。直到k !<len(s)

 

4. 给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。如果反转后整数超过 32 位的有符号整数的范围 [−231,  231 − 1] ,就返回 0。

思路: 先判断当前数是否超过范围。若在范围内,定义一个列表,先append符号位,注意先对x取绝对值,在以x对10取余,余数依次append进列表,当前数每次对10取整 减小。于是列表中就以逆序得到此数的各个位上的数字。最后从列表尾部开始,每个元素乘上10的对应次方相加即可。最后加上列表下标 0 处的正负号。

5.  字符串转换整数 (atoi):请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。函数 myAtoi(string s) 的算法如下:

读入字符串并丢弃无用的前导空格

检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。

读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。

将前面步骤读入的这些数字转换为整数(即,"123" -> 123, "0032" -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。

如果整数数超过 32 位有符号整数范围 [−231,  231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被固定为 −231 ,大于 231 − 1 的整数应该被固定为 231 − 1 。

思路:  正则表达式

6.  给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。

回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

例如,121 是回文,而 123 不是。负数永远不是

思路: 将X各个位数拆开放在列表中,头尾开始判断是否一致即可

7. 给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。

说明:你不能倾斜容器。

 思想: 容量由最短板决定

  8. 整数转罗马数字

 思想: 传进一个数x,先判断x在哪个区间内,再判断由几个一千,几个一百,几个十,几个1组成。再在对应区间内 将x的各个位数上的数字  转化为对应罗马数字。

9. 

 

 思想:挨个判断罗马字即可

10 . 编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 ""

思想:   先找到列表里最短的字符串,计算其长度,作为外层循环的控制条件。内层循环挨个遍历列表元素(字符串),通过外层指针比较每个字符串的相同位置是否相同。  注意结束循环判断:只要不相等,立刻结束内外两层循环。通过变量 b 将结束信号传递给外层。

 11. 

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请

你返回所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。(难点所在)

思路:双指针; 先排序,后找。两层循环:外层控制循环次数及一个值不动,内层循环在这个值后面从两端(因为有序)开始找。

 

 12. 

给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。

返回这三个数的和。假定每组输入只存在恰好一个解。

思路  ;与上题大致相同, 主要是判断当前三个数 之和与下一个三个数之和  哪一个与target更近。三重循环超过时间。所以双指针

point:  指针k 和 j 的移动

13.给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

 思路:  类似于以上两题;采用排序  后双指针的解法

 

14.    给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点

喜提创建头节点的方式 :dum=ListNode(0,head) :创建一个头结点,赋值0 并将next指向原本链表的头 

思路 : 计算原本链表的长度,删除倒数第n个就是顺数第length-n+1个。

创建一个头结点并链到原本的链表上,找到待删除节点的前一个。删除即可。注意返回的是不带此头结点的链表

 15. 给定一个只包括 '('')''{''}''['']' 的字符串 s ,判断字符串是否有效。有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。
  3. 每个右括号都有一个对应的相同类型的左括号。

 思路: :遇到左括号 则进栈;遇到右括号,先判断栈是否为空;再判断栈顶元素是否匹配.,若为空或不匹配直接False;若不为空且匹配,删除栈顶元素。

 

26. 给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 .

* 思想 :由于有序,相同的数字连续出现。 双指针法: 一快一慢,i 定位到与前面元素值相同的下标,j 找到与前面值不同的下标。若j 所指元素与前面元素值不同,则将j所指值 给i下标处,i,j同时后移;若j所指元素与前面元素值相同,i不动,j后移。

27. 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

思想:同上题,双指针法:i,j从0开始,若是val,j+=1,知道找到!=val的值,传递给i所指位置,i,j往后移;若不是,j的值给i,j+=1,i+=1             i,j之间的位置 都是可用的

28. 给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回  -1 。

思想:利用切片:找到从前往后遍历haystack,判断从当前位置开始,到与needle 字符串长度相同的位置,子集是否与needle相同,若相同,返回当前位置;若不同,当前位置往后移

29 . 给你两个整数,被除数 dividend 和除数 divisor。将两数相除,要求 不使用 乘法、除法和取余运算。整数除法应该向零截断,也就是截去(truncate)其小数部分。例如,8.345 将被截断为 8 ,-2.7335 将被截断至 -2 。返回被除数 dividend 除以除数 divisor 得到的  。

注意假设我们的环境只能存储 32 位 有符号整数,其数值范围是 [−231,  231 − 1] 。本题中,如果商 严格大于 231 − 1 ,则返回 231 − 1 ;如果商 严格小于 -231 ,则返回 -231 。

思想(位运算):  采用依次减去被除数统计次数的方式   会超过时间限制。故 采用 位运算的方式。除数左移一位(python位运算自动当做二进制进行),相当于扩大两倍,移两位,扩大四倍。从允许最大位数开始移动,为防止除数左移越界,将被除数右移缩小。

30.    给定一个字符串 s 和一个字符串数组 words words 中所有字符串 长度相同s 中的 串联子串 是指一个包含  words 中所有字符串以任意顺序排列连接起来的子串。

 思想: 哈希表   :用collections里的Counter方法,能够统计出列表里的元素及其对应数量。在挨个提取出相同长度的子字符串,以固定长度append进一个列表;在对子字符串同样 Counter方法,统计出其中各个单词及其数量,判断两个是否相等,若相等,返回子串在s中的首字符位置即可。

31. 整数数组的一个 排列  就是将其所有成员以序列或线性顺序排列。

  • 例如,arr = [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3][1,3,2][3,1,2][2,3,1] 。
  • 例如,arr = [1,2,3] 的下一个排列是 [1,3,2] 。
  • 类似地,arr = [2,3,1] 的下一个排列是 [3,1,2] 。
  • 整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中,那么数组的 下一个排列 就是在这个有序容器中排在它后面的那个排列。如果不存在下一个更大的排列,那么这个数组必须重排为字典序最小的排列(即,其元素按升序排列)。

思想:要点在与  下一个字典序更大的排列。从后往前找,找到一个位置i的值比它前面的值小,而后再次从最后面往前,找到一个值比它大,交换位置。而后让i后面的倒序。

38. 给定一个正整数 n ,输出外观数列的第 n 项.「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。 

思想: 双指针 :  后一项  由前一项决定;由给出的n控制循环次数,后将两个指针 从前一项第一位出发,快指针在小于前一项长度的前提下,往后找与慢指针不同的字符,若相同,继续往后,若不同,则停,计算与慢指针的距离,并转换成字符串+慢指针所指元素,存入变量cur;双指针再继续往后找。  最后快指针到前一项最后位置,所形成的cur即为前一项的后一项。

 

41. 给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。

思想: 要找最小的 未出现的正整数;所以在排序后,负数直接跳过;首先判断最小正整数1 在不在nums中,若不在,直接返回1;若在,定位到1的下标 index处,并从这个位置开始,判断后一项与前一项的差值 是否<=1,若是 则连续,指针继续往后,直到倒数第二个 ;否则,两数之间存在其他正整数,直接返回前一个数+1的结果;若到最后一个也连续,则返回最后一个数+1

48.旋转图像:给定一个 × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。

你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。

 思想:  观察 旋转前后的不同,发现规律,代码实现即可

策略: 先上下反转,再对角线反转

49   字母移位词分组:给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。

思想: 哈希表思想。从列表的第一项开始,若这个元素没有被归到哪一类中,则将它收进一个列表,通过 Counter函数 计算这一项里的字符及对应数量;再从这一项后挨个遍历,先判断遍历到的每一项有没有被收到列表里,若没有,则通过Counter计算字符及数量,若与那一项相同,则加入到那一项所在列表,并标记这一项,接着往后。

56  . 以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。

思想:先按照每个子列表的首个元素排序;再 慢指针指到一个元素,快指针判断其后的元素是否能与慢指针所指元素合并,若可以,则更新慢指针所指;慢指针在往后移

59 .  螺旋矩阵2.    给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。

 思想:      按照 规则,从从左到右,在从上到下,在从右到左,在从下到上,再以此循环填入递增的数字即可

60 排列序列: 

给出集合 [1,2,3,...,n],其所有元素共有 n! 种排列。

按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:

  1. "123"
  2. "132"
  3. "213"
  4. "231"
  5. "312"
  6. "321"

给定 n 和 k,返回第 k 个排列。

思想: 下一个排列的升级版。在下一个排列中,只用找到当前排列的下一个更大的排列。此题中,给定了 k值,输出第k个排列。所以在下一个排列的基础上,增加一个循环,让它找k-1次 下一个排列即可(k-1: 因为k=1,不应排列,按序输出即可)

61 给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。

 思想: 移动的特点在于:当移动的位置数等于链表长度时,链表就复原。

所以  分情况,若 链表长度小于向右移动的位置数,只用移动 k对链表长度的取余即可

                     若  链表长度大于向右移动的位置数,     找到移动前后的分界点即可。

66 . 加一   . 给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。你可以假设除了整数 0 之外,这个整数不会以零开头。

思想: 

69. x 的平方根  :给你一个非负整数 x ,计算并返回 x 的 算术平方根 。由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。

注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。

思想: 二分查找: 从0-x之间确定一个数mid,若mid的平方<=x,则更新mid值,一直找到最后

            数学思想求x的平方根,不能直接求,可以利用数学公式,转换形式,再求。

71 . 给你一个字符串 path ,表示指向某一文件或目录的 Unix 风格 绝对路径 (以 '/' 开头),请你将其转化为更加简洁的规范路径。在 Unix 风格的文件系统中,一个点(.)表示当前目录本身;此外,两个点 (..) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。任意多个连续的斜杠(即,'//')都被视为单个斜杠 '/' 。 对于此问题,任何其他格式的点(例如,'...')均被视为文件/目录名称。

请注意,返回的 规范路径 必须遵循下述格式:

  • 始终以斜杠 '/' 开头。
  • 两个目录名之间必须只有一个斜杠 '/' 。
  • 最后一个目录名(如果存在)不能 以 '/' 结尾。
  • 此外,路径仅包含从根目录到目标文件或目录的路径上的目录(即,不含 '.' 或 '..')。

返回简化后得到的 规范路径 。

思想: 简化路径,观察可得路径是由'/' 分开个目录,由此 先按照 '/'  划分,在按照规则:若是空格和‘.’ 直接跳过;若是‘..’,则返回栈顶元素;若 是其他,直接append进栈

最后栈里所剩的 就是简化后的规范路径  ,使用 ‘/’.join()连接起来

73. 矩阵置零  

给定一个 m x n 的矩阵,如果一个元素为 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法

思想  : 搞一个列表,记录0所在位置,第二遍遍历matrix时,用0替换所在行列值

86. 分隔链表

给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。

你应当 保留 两个分区中每个节点的初始相对位置

思想:  将值大于等于x的节点取出,构成新链表,并从原链表中删除x节点。最后将新链表接在原链表后面即可

88 . 合并两个有序数组

给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。

请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。

注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 

思想: 先将nums2 填到nums1中,在非递减排序

89 格雷编码n 位格雷码序列 是一个由 2n 个整数组成的序列,其中:

  • 每个整数都在范围 [0, 2n - 1] 内(含 0 和 2n - 1
  • 第一个整数是 0
  • 一个整数在序列中出现 不超过一次
  • 每对 相邻 整数的二进制表示 恰好一位不同 ,且
  • 第一个 和 最后一个 整数的二进制表示 恰好一位不同

给你一个整数 n ,返回任一有效的 n 位格雷码序列 

思想: 格雷编码:n=3的结果是依据n=2的结果的,在n=2的结果后加上n=2结果的反序,并将后部分值的2进制前加上1,得到n=3的结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值