![](https://img-blog.csdnimg.cn/20201014180756922.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
剑指offer
算法
爱哭的毛毛虫好汉歌
这个作者很懒,什么都没留下…
展开
-
剑指 Offer 25.合并两个排序的链表
题目输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。题目链接:合并两个排序的链表示例1:输入:1->2->4, 1->3->4输出:1->1->2->3->4->4代码实现 //非递归方式,这里必须要有一个辅助节点 时间复杂度:O(n + m) 空间复杂度:O(1) public static ListNode mergeTwoLists(ListNode l1, ListNode l2) {原创 2020-08-04 22:40:35 · 134 阅读 · 0 评论 -
剑指 Offer 24.反转链表
题目定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。题目链接:反转链表示例:输入: 1->2->3->4->5->NULL输出: 5->4->3->2->1->NULL思路要反转链表,目的就是要使指针指向前驱节点,因此需要保存前驱节点代码实现public ListNode reverseList(ListNode head) { ListNode pre = null; L原创 2020-08-04 22:35:12 · 139 阅读 · 0 评论 -
剑指offer23:链表中的环的入口节点
题目给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。思路链表中是否有环使用的是龟兔赛跑算法,或者是快慢指针代码实现public ListNode EntryNodeOfLoop(ListNode pHead) { ListNode meetNode = getMeetNode(pHead); if(meetNode==null){ return null; } ListNode nod原创 2020-08-04 22:29:44 · 106 阅读 · 0 评论 -
剑指 Offer 22. 链表中倒数第k个节点
题目输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如,一个链表有6个节点,从头节点开始,它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个节点是值为4的节点。题目链接:链表中倒数第k个节点](https://leetcode-cn.com/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof)示例:给定一个链表: 1->2->3->4->5,原创 2020-08-04 22:24:14 · 99 阅读 · 0 评论 -
剑指offer18-II 删除链表中重复的结点
题目在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5思路在待删除节点的前一个节点设置preNode指针,一直找到带删除节点的最后一个位置,将待删除节点的最后一个设置为preNode的next域。代码public static ListNode deleteDuplication(ListNode pHead) {原创 2020-08-04 22:16:27 · 82 阅读 · 0 评论 -
剑指offer18-1:在o(1)时间内删除链表
题目给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点。思路/删除节点通常的思路:找删除节点的前一个节点,需要遍历,时间复杂度为o(n),如果想要时间复杂度为o(1),那么可以使用待删除节点的后一个节点去覆盖待删除节点,然后再去删除后一个节点,这里有特殊情况,就是带删除节点是头结点,那么要将头结点置位空,如果带删除节点是链表的尾节点,那么只能从头遍历。代码实现 public static void deleteNode(ListNode head,ListNode pToBe原创 2020-08-04 22:13:04 · 123 阅读 · 0 评论 -
剑指 Offer 06. 从尾到头打印链表
题目输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。题目链接: 从尾到头打印链表示例 1:输入:head = [1,3,2]输出:[2,3,1]思路可以借助栈这种数据结构实现后进先出的案例。代码public static int[] reversePrint(ListNode head) { if(head==null){ return new int[0]; } Stack<ListNo原创 2020-08-04 22:07:53 · 77 阅读 · 0 评论 -
剑指 Offer 59 - I. 滑动窗口的最大值
题目给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。示例:输入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3输出: [3,3,5,5,6,7] 解释: 滑动窗口的位置 最大值--------------- -----[1 3 -1] -3 5 3 6 7 3 1 [3 -1 -3] 5 3 6 7 3 1 3 [-1 -原创 2020-07-30 22:48:12 · 109 阅读 · 0 评论 -
剑指 Offer 57 - II. 和为s的连续正数序列
题目输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。题目链接:和为s的连续正数序列示例 1:输入:target = 9输出:[[2,3,4],[4,5]]示例 2:输入:target = 15输出:[[1,2,3,4,5],[4,5,6],[7,8]]思路可以使用双指针,构建滑动窗口,需要注意的是,滑动窗口的区间是左闭右开,即[i,j),并且滑动窗口只向右移动。代码实现/原创 2020-07-30 22:43:00 · 111 阅读 · 0 评论 -
剑指 Offer 56 - I. 数组中只出现一次的两个数字
题目一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。题目链接: 数组中只出现一次的两个数字示例 1:输入:nums = [4,1,4,6]输出:[1,6] 或 [6,1]示例 2:输入:nums = [1,2,10,4,1,4,3,3]输出:[2,10] 或 [10,2]思路任何数和本身异或则为0,任何数和 0 异或是本身。我们依旧从头到尾异或每个数字,那么最终的结果就是这两个只出现原创 2020-07-30 22:37:12 · 100 阅读 · 0 评论 -
剑指 Offer 53 - II. 0~n-1中缺失的数字
题目一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。示例 1:输入: [0,1,3]输出: 2示例 2:输入: [0,1,2,3,4,5,6,7,9]输出: 8思路使用二分查找,如果中间的数字m=nums[m],说明从0~m下标与数字对应的数字都是一一对应的,那么就向右查找,否则就向左查找。代码实现public static int missingNumber(in原创 2020-07-30 22:31:43 · 84 阅读 · 0 评论 -
剑指 Offer 53 - I. 在排序数组中查找数字 I
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。你的算法时间复杂度必须是 O(log n) 级别。如果数组中不存在目标值,返回 [-1, -1]。题目链接:在排序数组中查找数字 I示例 1:输入: nums = [5,7,7,8,8,10], target = 8输出: [3,4]示例 2:输入: nums = [5,7,7,8,8,10], target = 6输出: [-1,-1]思路由于本题要求的算法时间复杂度原创 2020-07-30 22:09:57 · 77 阅读 · 0 评论 -
剑指 Offer 51. 数组中的逆序对
题目在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。题目链接:剑指 Offer 51. 数组中的逆序对示例 1:输入: [7,5,6,4]输出: 5思路使用归并排序,重点在于合的过程中,使用两个指针指向数组的末尾,使用一个指针指向临时数组的末尾。如果第一个子数组中的数字大于第二个子数组的数字,那么则构成逆序对,并且逆序对的数目等于等于第二个数组中剩余数字的个数。代码实现//时间复杂度0(nlogn),空间复杂度o原创 2020-07-30 22:00:22 · 94 阅读 · 0 评论 -
剑指 Offer 45. 把数组排成最小的数
题目输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。题目链接:把数组排成最小的数示例 1:输入: [10,2]输出: "102"示例 2:输入: [3,30,34,5,9]输出: "3033459"思路本题实质上是排序,但是这个排序不仅仅是比较数值的大小,还包括字符串的比较,时间复杂度o(nlogn) 空间复杂度o(n)。具体排序规则如下:如果 x+y>y+x 那么我们就说想x<y如果x+y<y+x 那么我们就说原创 2020-07-30 21:55:07 · 78 阅读 · 0 评论 -
剑指 Offer 42. 连续子数组的最大和连续子数组的最大和
题目输入一个整型数组,数组里有正数也有负数。数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。题目链接:连续子数组的最大和连续子数组的最大和示例1:输入: nums = [-2,1,-3,4,-1,2,1,-5,4]输出: 6解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。思路因为本题要求的时间复杂度是O(N),所以说只能遍历一遍数组,这里可以使用动态规划思想。具体步骤如下:1.首先对数组进行遍历,当前最大连续子序列和为 sum原创 2020-07-30 21:45:47 · 98 阅读 · 0 评论 -
剑指 Offer 40. 最小的k个数
题目输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。题目链接:最小的k个数示例 1:输入:arr = [3,2,1], k = 2输出:[1,2] 或者 [2,1]示例 2:输入:arr = [0,1,2,1], k = 1输出:[0]思路这类问题属于Topk问题,解决这类问题主要有两种思路。方式1 快排变形基于快排的变形,基于数组的第k个数字来调整,是小于k的数字都在k的左边(这k个数字不一原创 2020-07-30 21:36:31 · 88 阅读 · 0 评论 -
剑指 Offer 39. 数组中出现次数超过一半的数字
题目数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。你可以假设数组是非空的,并且给定的数组总是存在多数元素。题目链接:数组中出现次数超过一半的数字示例 1:输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]输出: 2思路方式1 排序,取中间public int majorityElement(int[] nums) { Arrays.sort(nums); return nums[nums.length/2]; }时间原创 2020-07-28 09:13:52 · 87 阅读 · 0 评论 -
剑指 Offer 29. 顺时针打印矩阵
题目输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。题目链接:顺时针打印矩阵示例 1:输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]输出:[1,2,3,6,9,8,7,4,5]示例 2:输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]输出:[1,2,3,4,8,12,11,10,9,5,6,7]思路就像剥橘子皮一样,由外向内逐层按照顺时针的顺序逐层剥橘子皮。代码实现 //思路:由外向内,逐层打原创 2020-07-28 09:03:38 · 207 阅读 · 0 评论 -
剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
题目输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。题目链接:调整数组顺序使奇数位于偶数前面示例:输入:nums = [1,2,3,4]输出:[1,3,2,4] 注:[3,1,2,4] 也是正确的答案之一。思路使用双指针,分别指向数组的开始和结尾位置,分别判断各种情况。代码实现public static int[] exchange(int[] nums) { int low = 0;原创 2020-07-28 08:54:46 · 60 阅读 · 0 评论 -
剑指offer11:旋转数组的最小数字
题目把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。题目链接:旋转数组的最小数字示例 1:输入:[3,4,5,1,2]输出:1示例 2:输入:[2,2,2,0,1]输出:0思路最简单的方式就是使用暴力方式,循环遍历数组寻找数组的最小值。但是这种方式没有利用题目中旋转数组的特点,仔细观察题目以最小值为分界线两边是有序原创 2020-07-28 08:50:28 · 84 阅读 · 0 评论 -
剑指offer4:二维数组的查找
题目在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。题目链接:二维数组的查找示例:现有矩阵 matrix 如下:[ [1, 4, 7, 11, 15], [2, 5, 8, 12, 19], [3, 6, 9, 16, 22], [10, 13, 14, 17, 24], [18, 21, 23, 26, 30]]给定 t原创 2020-07-27 22:30:31 · 51 阅读 · 0 评论 -
剑指offer57-1:和为s的两个数字
题目输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。题目链接:和为s的两个数字示例 1:输入:nums = [2,7,11,15], target = 9输出:[2,7] 或者 [7,2]示例 2:输入:nums = [10,26,30,31,47,60], target = 40输出:[10,30] 或者 [30,10]思路使用双指针,分别指向数组的开头和结尾。如果两个两个指针对应的值大于target,尾指原创 2020-07-27 22:22:32 · 59 阅读 · 0 评论 -
剑指offer3-2:不修改数组找出重复的数字
题目在一个长度为n+1的数组里的所有数字都在1到n的范围内,所以数组中至少有一个数字是重复的。请找出数组中任意一个重复的数字,但不能修改输入的数组。例如,如果输入长度为8的数组{2, 3, 5, 4, 3, 2, 6, 7},那么对应的输出是重复的数字2或者3。思路方式1 使用哈希表public static boolean duplicate2(int numbers[], int length, int[] duplication) { //判断数组是否非法 i原创 2020-07-27 22:10:06 · 113 阅读 · 0 评论 -
剑指offer3-1:找出数组中重复的数字
题目在一个长度为n的数组里的所有数字都在0到n-1的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。例如,如果输入长度为7的数组{2, 3, 1, 0, 2, 5, 3},那么对应的输出是重复的数字2或者3。思路第1种 暴力方式使用排序算法将数组进行排序,遍历数组,比较数组中的重复项。public static boolean duplicate1(int numbers[], int length, int[] duplica原创 2020-07-25 15:37:03 · 79 阅读 · 0 评论