LeetCode每日刷题:hashmap+动态规划

1.hashmap:最长不含重复字符的子字符串

在这里插入图片描述

class Solution {
    public int lengthOfLongestSubstring(String s) {
        if(s==null || s.length()==0){
            return 0;
        }
        char[] c=s.toCharArray();
        int start=0,maxLength=0;
        HashMap<Character,Integer> memo=new HashMap<>();
        for(int i=0;i<c.length;i++){
            int tempLen=0;//临时长度记录,用于更新最大长度
            //如果map中不包含该元素,则添加
            if(!memo.containsKey(c[i])){
                memo.put(c[i],i);
            }else{
                //否则就要一系列操作:
                //(1)获取已存在元素的下标
                //(2)更新start位置,目的是为了从重复元素的下一位置开始计算长度
                int index=memo.get(c[i]);
                //从重复元素的下一个位置开始计算长度,替换之前和原来的start位置进行比较
                //取二者比较大的值,因为不能让start位置往回走,前面已经比较过了
                start=Math.max(start,index+1);
                memo.put(c[i],i);
            }
            tempLen=i-start+1;
            maxLength=Math.max(maxLength,tempLen);
        }
        return maxLength;
    }
}

2.动态规划:丑数

在这里插入图片描述

class Solution {
    public int nthUglyNumber(int n) {
        //动态规划
        //每个丑数的获得=更小的丑数*因子(2,3,5)
        int[] dp=new int[n];
        dp[0]=1;

        int a=0,b=0,c=0;//分别记录都哪些数乘过2,3,5了

        for(int i=1;i<n;i++){
            int n2=dp[a]*2,n3=dp[b]*3,n5=dp[c]*5;
            dp[i]=Math.min(Math.min(n2,n3),n5);
            if(dp[i]==n2){
                a++;
            }
            if(dp[i]==n3){
                b++;
            }
            if(dp[i]==n5){
                c++;
            }
        }
        return dp[n-1];
    }
}

题解LeetCode
还是很懵。。。。不太懂

3.hashmap:第一个只出现一次的字符

在这里插入图片描述

class Solution {
    public char firstUniqChar(String s) {
        char[] c=s.toCharArray();
        HashMap<Character,Integer> map=new HashMap<>();
        for(char ch:c){
            map.put(ch,map.getOrDefault(ch,0)+1);
        }
        for(int i=0;i<s.length();i++){
            if(map.get(c[i])==1){
                return c[i];
            }
        }
        return ' ';
    }
}

4.hashset:两个链表的第一个节点

在这里插入图片描述

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        Set<ListNode> set=new HashSet<>();
        while(headA!=null){
            set.add(headA);
            headA=headA.next;
        }
        while(headB!=null){
            if(!set.contains(headB)){
                headB=headB.next;
            }else{
                return headB;
            }
        }
        return null;
    }
}

5.hashmap+二分法求边界:在排序数组中查找数字1

在这里插入图片描述

class Solution {
    public int search(int[] nums, int target) {
        //1.hash表
        // HashMap<Integer,Integer> map=new HashMap<>();
        // for(int i:nums){
        //     map.put(i,map.getOrDefault(i,0)+1);
        // }
        // return map.getOrDefault(target,0);

        //2.二分法找到左右边界,左右边界的长度就是元素个数
        if(nums.length==0) return 0;
        int left=0,right=nums.length;
        //找左边界
        while(left<right){
            int mid=left+(right-left)/2;
            if(nums[mid]<target){
                left=mid+1;
            }else if(nums[mid]>target){
                right=mid;
            }else{
                right=mid;
            }
        }
        int left_bound=right;
        //如果左边界不等于target,则证明没找到,这个数组里没有该元素
        if(left_bound<nums.length && nums[left_bound]!=target){
            return 0;
        }

        left=0;
        right=nums.length;
        //找右边界
        while(left<right){
            int mid=left+(right-left)/2;
            if(nums[mid]<target){
                left=mid+1;
            }else if(nums[mid]>target){
                right=mid;
            }else{
                left=mid+1;
            }
        }
        int right_bound=right-1;
        return right_bound-left_bound+1;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值