热点新闻
LeetCode之双指针法
2023-07-14 15:51  浏览:527  搜索引擎搜索“手机展会网”
温馨提示:信息一旦丢失不一定找得到,请务必收藏信息以备急用!本站所有信息均是注册会员发布如遇到侵权请联系文章中的联系方式或客服删除!
联系我时,请说明是在手机展会网看到的信息,谢谢。
展会发布 展会网站大全 报名观展合作 软文发布

双指针是一种思想或一种技巧并不是特别具体的算法。
具体就是用两个变量动态存储两个结点,来方便我们进行一些操作。通常用在线性的数据结构中。

三数之和

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

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

注意:答案中不可以包含重复的三元组。

题解:

class Solution { public List<List<Integer>> threeSum(int[] nums) { List<List<Integer>> list = new ArrayList<>(); Arrays.sort(nums); //排序 int left = 0, right = 0; for (int i=0;i<nums.length;i++) { if (nums[i] > 0) { //当前最小数大于0,则找不到符合条件的组 return list; } if (i>0 && nums[i] == nums[i-1]) { //对i去重: 如果当前组的a和上一组的a相等,则视为重复组 continue; } left = i+1; right = nums.length-1; while(left<right) { int temp = nums[i] + nums[left] + nums[right]; if (temp > 0) { right--; } else if (temp < 0) { left++; } else { //找到符合条件组 list.add(Arrays.asList(nums[i], nums[left], nums[right])); //将b c相同元素跳过,即去重 while(left < right && nums[left+1] == nums[left]) { //将b去重 left++; } while(left < right && nums[right-1] == nums[right]) { //将c去重 right--; } left++; right--; } } } return list; } }

环形链表 II

给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

不允许修改 链表。

题解:

public class Solution { public ListNode detectCycle(ListNode head) { //题解:这个题的目标,是找到环的入环点, // 根据上图,首先根据公式推导出 a = (n-1)(b+c) + c,通过这个公式, // 再用两个指针相同速度走,相遇点就是要返回的入环节点 //那么第一步:定义一个快指针和慢指针,快指针每步走2个,慢指针每步走一个,在有环的情况下快指针一定会追上慢指针相遇 //得到相交点,构成这幅图的形式 ListNode slow = head, fast = head; while(fast != null) { //让慢指针每次走1步,快指针每次走2步 slow = slow.next; if (fast.next != null) { fast = fast.next.next; } else { return null; } if (slow == fast) { //再构造两个慢指针走到入环节点 ListNode cur = head; while(cur != slow) { cur = cur.next; slow = slow.next; } return cur; } } return null; } }

颜色分类

给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

必须在不使用库内置的 sort 函数的情况下解决这个问题。

题解:

4. 双单指针法 public void sortColors(int[] nums) { int n = nums.length; int p0 = 0, p1 = 0; for (int i = 0; i < n; ++i) { if (nums[i] == 1) { swap(nums,i,p1); p1++; } else if (nums[i] == 0) { swap(nums,i,p0); if (p0 < p1) { swap(nums,i,p1); } p0++; p1++; } } }

合并两个有序数组

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

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

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

题解:

public void merge(int[] nums1, int m, int[] nums2, int n) { //思路:双指针法 // 创建数组nums3,遍历nums3,num1和nums2分别定义下标pos1,pos2,两个指针数元素比较大小,小的放入nums3中,相等的将num1的放入nums3中 int p1 = 0, p2 = 0; int[] nums3 = new int[m+n]; //创建总长度m+n的数组存所有元素 int cur; //当前应该插入的值 while(p1<m || p2<n) { //循环条件是p1<m,p2<n,或者的关系,一个结束另一个继续提交,知道两者都结束,则全部结束 if (p1 == m) { //nums1结束,但是nums2没有结束 cur = nums2[p2++]; } else if (p2 == n) { //nums2结束,但是nums1没有结束 cur = nums1[p1++]; } else if (nums1[p1] <= nums2[p2]) { //都没有结束,选择小的 cur = nums1[p1++]; } else { cur = nums2[p2++]; } nums3[p1+p2-1] = cur; //当前该插入的位置为p1+p2-1 } for(int i=0;i<m+n;i++) { //将nums3中所有元素导到nums1中 nums1[i] = nums3[i]; } }

移动零

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

请注意 ,必须在不复制数组的情况下原地对数组进行操作。

题解:

public void moveZeroes(int[] nums) { //思路:双指针:指针i每遇到一个非0元素,就将慢指针j位置数设置为nums[i],直到nums遍历完成 //在j位置之后的元素都置为0,完成移动 int j=0; for (int i=0;i<nums.length;i++) { if (nums[i] != 0) { nums[j++] = nums[i]; } } for (int i = j;i<nums.length;i++) { nums[i] = 0; } }

发布人:ccb9****    IP:125.64.72.***     举报/删稿
展会推荐
让朕来说2句
评论
收藏
点赞
转发