From 44972c359c63b326ec27f8f4fae82d40ee1c9a09 Mon Sep 17 00:00:00 2001 From: chefyuan Date: Fri, 19 Mar 2021 19:04:42 +0800 Subject: [PATCH] test --- .../数组篇/leetcode41缺失的第一个正数.md | 111 ++++++++++++++++++ gif-algorithm/链表篇/分隔链表.md | 73 ++++++++++++ 2 files changed, 184 insertions(+) create mode 100644 gif-algorithm/数组篇/leetcode41缺失的第一个正数.md create mode 100644 gif-algorithm/链表篇/分隔链表.md diff --git a/gif-algorithm/数组篇/leetcode41缺失的第一个正数.md b/gif-algorithm/数组篇/leetcode41缺失的第一个正数.md new file mode 100644 index 0000000..38c15b0 --- /dev/null +++ b/gif-algorithm/数组篇/leetcode41缺失的第一个正数.md @@ -0,0 +1,111 @@ +#### 41. 缺失的第一个正数 + +给你一个未排序的整数数组,请你找出其中没有出现的最小的正整数。 + +示例 1: + +> 输入: [1,2,0] +> 输出: 3 + +示例 2: + +> 输入: [3,4,-1,1] +> 输出: 2 + +示例 3: + +> 输入: [7,8,9,11,12] +> 输出: 1 + +### 重复遍历 + +让我们找出缺失的最小正整数,而且这是一个未排序的数组,我们可以利用暴力求解,挨个遍历发现那个不存在直接返回即可。我们这里使用两种方法解决这个问题,大家也可以提出自己的做法。 + +我们既然是返回缺失的正整数,那么我们则可以将这个数组中的所有正整数保存到相应的位置,见下图。 + +![微信截图_20210109135536](https://cdn.jsdelivr.net/gh/tan45du/github.io.phonto2@master/myphoto/微信截图_20210109135536.41h4amio2me0.png) + +上图中,我们遍历一遍原数组,将正整数保存到新数组中,然后遍历新数组,第一次发现 newnum[i] != i 时,则说明该值是缺失的,返回即可,例如我上图中的第一个示例中的 2,如果遍历完新数组,发现说所有值都对应,说明缺失的是 新数组的长度对应的那个数,比如第二个示例中 ,新数组的长度为 5,此时缺失的为 5,返回长度即可,很容易理解。 + +注:我们发现我们新的数组长度比原数组大 1,是因为我们遍历新数组从 1,开始遍历。 + +动图解析 + +![缺失的第一个正数](https://cdn.jsdelivr.net/gh/tan45du/github.io.phonto2@master/myphoto/缺失的第一个正数.1it1cow5aa8w.gif) + +```java +class Solution { + public int firstMissingPositive(int[] nums) { + if (nums.length == 0) { + return 1; + } + //因为是返回第一个正整数,不包括 0,所以需要长度加1,细节1 + int[] res = new int[nums.length + 1]; + //将数组元素添加到辅助数组中 + for (int x : nums) { + if (x > 0 && x < res.length) { + res[x] = x; + } + } + //遍历查找,发现不一样时直接返回 + for (int i = 1; i < res.length; i++) { + if (res[i] != i) { + return i; + } + } + //缺少最后一个,例如 1,2,3此时缺少 4 ,细节2 + return res.length; + } +} +``` + + + +我们通过上面的例子了解这个解题思想,我们有没有办法不使用辅助数组完成呢?我们可以使用原地置换,直接在 nums 数组内,将值换到对应的索引处,与上个方法思路一致,只不过没有使用辅助数组,理解起来也稍微难理解一些。 + +下面我们看一下原地置换的一些情况。 + +注:红色代表待置换,绿色代表置换完毕 + +![置换1](https://cdn.jsdelivr.net/gh/tan45du/github.io.phonto2@master/myphoto/置换1.4j4pcz56ml40.png) + +![置换2](https://cdn.jsdelivr.net/gh/tan45du/github.io.phonto2@master/myphoto/置换2.5rawbyws7h40.png) + +动图解析: + +![原地置换](https://cdn.jsdelivr.net/gh/tan45du/github.io.phonto2@master/myphoto/原地置换.52wi0yoiu3o0.gif) + +题目代码: + +```java +class Solution { + public int firstMissingPositive(int[] nums) { + int len = nums.length; + if (len == 0) { + return 1; + } + for (int i = 0; i < len; ++i) { + //需要考虑指针移动情况,大于0,小于len+1,不等与i+1,两个交换的数相等时,防止死循环 + while (nums[i] > 0 && nums[i] < len + 1 && nums[i] != i+1 && nums[i] != nums[nums[i]-1]) { + swap(nums,i,nums[i] - 1); + } + } + //遍历寻找缺失的正整数 + for (int i = 0; i < len; ++i) { + if(nums[i] != i+1) { + return i+1; + } + } + return len + 1; + } + //交换 + public void swap(int[] nums, int i, int j) { + if (i != j) { + nums[i] ^= nums[j]; + nums[j] ^= nums[i]; + nums[i] ^= nums[j]; + } + } +} +``` + diff --git a/gif-algorithm/链表篇/分隔链表.md b/gif-algorithm/链表篇/分隔链表.md new file mode 100644 index 0000000..7d66080 --- /dev/null +++ b/gif-algorithm/链表篇/分隔链表.md @@ -0,0 +1,73 @@ +给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 + +你应当 保留 两个分区中每个节点的初始相对位置。 + +![](https://img-blog.csdnimg.cn/20210319190335143.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMzODg1OTI0,size_16,color_FFFFFF,t_70) + +示例 1: + + +输入:head = [1,4,3,2,5,2], x = 3 +输出:[1,2,2,4,3,5] +示例 2: + +输入:head = [2,1], x = 2 +输出:[1,2] + +来源:力扣(LeetCode) + +这个题目我的做题思路是这样的,我们先创建一个侦察兵,侦察兵负责比较链表值和 x 值,如果 >= 的话则接在 big 链表上,小于则接到 small 链表上,最后一个细节就是我们的 big 链表尾部要加上 null,不然会形成环。这是这个题目的一个小细节,很重要。 + +中心思想就是,将链表先分后合。 + +下面我们来看模拟视频吧。希望能给各位带来一丢丢帮助。 + +![](https://img-blog.csdnimg.cn/20210319190417499.gif) + +**题目代码** + +```java +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode(int x) { val = x; } + * } + */ +class Solution { + public ListNode partition(ListNode head, int x) { + if (head == null) { + return head; + } + ListNode pro = head; + ListNode big = new ListNode(-1); + ListNode small = new ListNode(-1); + ListNode headbig = big; + ListNode headsmall =small; + //分 + while (pro != null) { + //大于时,放到 big 链表上 + if (pro.val >= x) { + big.next = pro; + big = big.next; + // 小于放到 small 链表上 + }else { + small.next = pro; + small = small.next; + } + pro = pro.next; + } + //细节 + big.next = null; + //合 + small.next = headbig.next; + return headsmall.next; + } +} +``` + + + + +