力扣算法题

1.合并两个有序数组(简单)

给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。

初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。你可以假设 nums1 的空间大小等于 m + n,这样它就有足够的空间保存来自 nums2 的元素。
在这里插入图片描述

(1)解法一,挺快的但是需要用到辅助空间
class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int[] mergeArray=new int[m+n];
        int k=0;
        int i=0;
        int j=0;
        while(i<m&&j<n){
            if(nums1[i]<=nums2[j]){
                mergeArray[k++]=nums1[i++];
            }
            else{
                mergeArray[k++]=nums2[j++];
            }
        }
        while(i<m){
            mergeArray[k++]=nums1[i++];
        }
        while(j<n){
            mergeArray[k++]=nums2[j++];
        }
        for(int z=0;z<m+n;z++){
            nums1[z]=mergeArray[z];
        }
    }
}
(2)从后往前,观察到nums1是大小为m+n的数组,m位之后全是0,可以从后往前以谁大先确定谁位置,不需要额外的存储空间,而且最后只需要管如果nums2数组没走完但是nums1数组走完了该怎么办的情况,因为此时nums1的前面一定是走完了的。主要还是要根据最终情况进行分析。
class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int k=m+n-1;  //数组的最后一个位置。
        int i=m-1;    //nums1最后一个位置
        int j=n-1;    //nums2最后一个位置
        while(i>=0&&j>=0){
            if(nums1[i]>=nums2[j]){
                nums1[k--]=nums1[i--];
            }
            else{
                nums1[k--]=nums2[j--];
            }
        }
        while(j>=0){
            nums1[k--]=nums2[j--];
        }
    }
}

在这里插入图片描述

2.无重复字符的最长子串

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。

在这里插入图片描述

class Solution {
    public int lengthOfLongestSubstring(String s) {
        //到一个位置i之后先判断该位置的字符是否出现过,未出现过那么就设记录位置值为i,
        //否则就拿最近一次出现的地点与我们的窗口开始处start进行对比,
        //如果start<location说明重复,需要将start移到location+1的位置,
        //修改该字符最近一次出现的位置并计算字符串长度,与之前的maxlength取max。
        int []location=new int[129];  //记录每个字符最近一次出现的位置
        int start=1;
        int maxLength=0;
        for(int i=0;i<s.length();i++){
            int index=location[s.charAt(i)];
            if(index!=0){
                if(start<=index){  //说明窗口已包含该字符
                    start=index+1;
                }
            }
            location[s.charAt(i)]=i+1;
            maxLength=maxLength>(i-start+2)? maxLength:(i-start+2);
        }
        return maxLength;
    }
}

在这里插入图片描述

(3)法二:长短指针+hashmap法

其实就是i指向连续字符串开始的地方,j指向当前连续字符串结束的地方,然后比较啥的都跟上面想法一样,不一样的点在于,上面一题是记录每个出现的字符最近一次出现的位),但是本道解法是记录每个出现的字符的频数(并且这个频数特指在这个子段内的包含边界的出现的频数!!!),一旦超过两一,那么就有重复,需要我们将i向前挪动,挪动的过程中会将挪动时遇到的字符的频数均减1,表示他们离开了当前子段的范围。一直到找到段内重复的那个字符减一之后hashmap[s.charAt(j)]>1不成立为止。

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int hashmap[]=new int[129];  //记录每个字符最近一次出现的位置
        int i=0;
        int j=0;
        int max=0;
        for(i=0,j=0;j<s.length();j++){
            int index=s.charAt(j);
            hashmap[index]++;
            while(hashmap[index]>1){
                hashmap[s.charAt(i++)]--;
            }
            if(max<(j-i+1)){
                max=j-i+1;
            }
        }
        return max;
    }
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值