欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > 大厂高频算法考点--双指针

大厂高频算法考点--双指针

2024/10/23 23:30:32 来源:https://blog.csdn.net/hdk5855/article/details/142921522  浏览:    关键词:大厂高频算法考点--双指针

数指针是一个很常见的技巧,为大家提供了leetcode的练习题和答案。

问题一:922. 按奇偶排序数组 II - 力扣(LeetCode)
class Solution {public int[] sortArrayByParityII(int[] nums) {//题目写了这个数组就是大与2的//分析题目,将技术放置在下标是奇数的位置  偶数放置在下表是偶数的位置//双指针的方式解决这个问题//在考虑一个问题,是将双指针设置为标int even =0;int odd=1;while(even<nums.length){while(nums[even]%2!=0){swap(nums,even,odd);if(odd+2>nums.length-1){break;}else{odd+=2;}}even+=2;}return nums;}private void swap(int[] arr,int a,int b){int temp =arr[a];arr[a]=arr[b];arr[b]=temp;}
}
问题二:287. 寻找重复数 - 力扣(LeetCode)
class Solution {public int findDuplicate(int[] nums) {//这个问题真的很像单链表的查找入环节点  就是将他包装为单链表,但是如何包装呢//使用数组和下标进行包装  我们吧当前位置的值设置为就是他下一个位置的下标if(nums.length<=2){return nums[0];}int slow=nums[0];int fast=nums[nums[0]];while(slow!=fast){slow=nums[slow];fast=nums[nums[fast]];}fast=0;while(fast!=slow){fast=nums[fast];slow=nums[slow];}return fast;//指针的值是下标}
}
问题三:42. 接雨水 - 力扣(LeetCode)
方法一:浪费空间,未经优化
class Solution {public int trap(int[] height) {//采取两种方式  //直接在创建两个数组  记录每个点左右的的比他大的值//第一个数组是记录在0~i位置上的最大值//第二个数组就是记录在i~n-1的最大值//如果求解i的位置的话,就直接使用数组lmax的i-1的值,和rmax的i+1的值。int n=height.length;int[] lmax=new int[n];int[] rmax=new int[n];lmax[0]=height[0];for(int i=1;i<n;i++){lmax[i]=Math.max(lmax[i-1],height[i]);}rmax[n-1]=height[n-1];for(int i=n-2;i>=0;i--){rmax[i]=Math.max(rmax[i+1],height[i]);}int ans=0;for(int i=1;i<n-1;i++){ans+=Math.min(lmax[i-1],rmax[i+1])-height[i]>=0?Math.min(lmax[i-1],rmax[i+1])-height[i]:0;}return ans;}
}
方法二:不会创建新的数组

接雨水规律:如果现在右侧的最大高度>左侧,那就计算左侧的接雨水点,反之亦然

public static int trap(int[] height){//优化的版本,不会创建新的数组,但是需要思考的过程//总结就是一句话:如果现在右侧的最大高度>左侧,那就计算左侧的接雨水点,反之亦然//因为如果现在右侧的高度已经大于左侧了,木桶原理,受限的原因一定是短板,右侧的高度一定不会比现在小,但是左面的高度不会半大,已经确定//我能确定的最大值就是最小值int n=height.length;int l=0;int r=n-1;int lmax=height[0];int rmax=height[n-1];int ans=0;while(l<r&&(l<n-1&&r>0)){if(lmax<=rmax){l++;ans+=lmax-height[l]>=0?lmax-height[l]:0;lmax=Math.max(height[l],lmax);}else{r--;ans+=rmax-height[r]>=0?rmax-height[r]:0;rmax=Math.max(height[r],rmax);}}return ans;}
问题四:881. 救生艇 - 力扣(LeetCode)
class Solution {public int numRescueBoats(int[] people, int limit) {Arrays.sort(people);//将数组排序int l=0,r=people.length-1;int ans=0;while(l<=r){if(people[l]+people[r]<=limit){l++;r--;ans++;}else{r--;ans++;}}return ans;}
}
问题五:11. 盛最多水的容器 - 力扣(LeetCode)
class Solution {public int maxArea(int[] height) {
​//思路就是短板效应,如果你现在得值是小的,那你就计算面积int l = 0;int r =height.length-1;int ans=0;while(l<=r){if(height[l]<=height[r]){ans=Math.max((r-l)*height[l],ans);l++;}else{ans=Math.max((r-l)*height[r],ans);r--;}}return ans;}
}
问题六:475. 供暖器 - 力扣(LeetCode)
方法一:暴力方式

因为数组的长度是10^4所以即使是n*n的操作也不会超时,所以这道题可以暴力,但是如果暴力的话效率低

public int findRadius(int[] houses, int[] heaters) {int ans=0;//无需创建数组,直接相减就行for(int i=0;i<houses.length;i++){int count=Integer.MAX_VALUE;for(int j=0;j<heaters.length;j++){count=Math.min(count,getNum(houses[i]-heaters[j]));}ans=Math.max(count,ans);}return ans;}public int getNum(int n){return n>=0?n:-n;}
方法二:双指针

我感觉这个解体方法很美妙

​class Solution {public int findRadius(int[] houses, int[] heaters) {Arrays.sort(houses);Arrays.sort(heaters);int ans=0;//使用双指针解决问题//将r指针的移动就是在查找到位置是才会移动//特别注意的是我们收集的答案时同一个房间的最短距离,但是房间之间我们收集的是最大值//注意这个数组的数据必须是有序的int l =0;int r=0;for(l=0;l<houses.length;l++){while(!best(houses,heaters,l,r)){//这里面直接比较出来房间里的最小的值了r++;}//现在直接比较房间与房间之间的最大值ans=Math.max(ans,Math.abs(houses[l]-heaters[r]));}return ans;}public boolean best(int[] houses,int[] heaters,int i,int j){//之里面一定是>  我么的设定就是即使时相等时,就必须要前进return  j==heaters.length-1  ||Math.abs(houses[i]-heaters[j+1])- Math.abs(houses[i]-heaters[j])>0;}
}
问题七41. 缺失的第一个正数 - 力扣(LeetCode)

class Solution {
    //整体的思路如下
    //因为数值在设计这个题目时设定,如果长度是n的数组,那他每个位置的值就在n-1处,所以最佳状态
    //是缺的就是第n+1的数字
    //使用双指针去解决问题,将l指针放置在0位置,r指针放置在n位置,注意是n位置,不是n-1,我们将要维护一个无效区
    //哪几种情况数值无效,
    //1.数值大小《=0  或者是当前的下表是3 但是这个数比4小
    //2.当前的之大于r
    //3.如果当前值就是n在n-1位置,l++
    //如果现在的数字是4  但是你的三位置放置了4 那就是垃圾
  
 public   int firstMissingPositive(int[] arr) {
    int l=0;
    int r=arr.length;
    while(l<r){
        if(arr[l]==l+1){
            l++;
        }else if (arr[l]>r||arr[l]<=l||arr[l]==arr[arr[l]-1]){
            swap(arr,l,--r);
        }else{
            swap(arr,l,arr[l]-1);//现在就是数值时合法的,该如何计算  5   
        }
    }
    return l+1;
 }
    public   void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com