部分简单算法(持续更新)

注:代码基于力扣上的题目,但不一定是题目的最优解,如有出错可随时联系

二分查找(升序查找)

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。(力扣题号704)

左闭右开区间

class Solution {
    public int search(int[] nums, int target) {
        int l = 0, r = nums.length;
        while (l < r) {
            int mid = l + ((r - l) / 2);// 防止溢出,等同于(l+r)/2
            if (nums[mid] == target)
                return mid;
            else if (nums[mid] < target)
                l = mid + 1;
            else if (nums[mid] > target)
                r = mid;
        }
        return -1;
    }
}

 哈希(数组、Set、Map)

优先使用顺序:数组 > Set > Map

判断是否为有效字母异位词(力扣题号242)

利用ASCII码和哈希数组对字符串的判断

class Solution {
    public boolean isAnagram(String s, String t) {
        int n = s.length();
        int m = t.length();
        if(n != m) return false;
        int[] hash = new int[26];

        for(int i = 0; i < n; i++){
            hash[s.charAt(i) - 'a'] ++;//ASCII码转换到数组进行加减
        }

        for(int i = 0; i < m; i++){
            hash[t.charAt(i) - 'a'] --;
        }
        for(int i = 0; i < 26; i++){
            if(hash[i] != 0) return false;
        }
        return true;
    }
}
返回同一异位词的数组列表 (力扣题号49)
class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        // 创建一个 HashMap,用于存储分组后的字母异位词,键为排序后的字符串,值为字符串列表
        Map<String, List<String>> map = new HashMap<String, List<String>>();
        // 遍历给定的字符串数组
        for (String str : strs) {
            char[] array = str.toCharArray(); // 将当前字符串转换为字符数组
            Arrays.sort(array); // 对字符数组进行排序,实现字母异位词的统一表示
            String key = new String(array); // 将排序后的字符数组转换为字符串作为 key
            
            // 获取 key 对应的值列表,如果不存在则创建一个新的列表
            List<String> list = map.getOrDefault(key, new ArrayList<String>());
            list.add(str); // 将当前字符串添加到值列表中
            map.put(key, list); // 更新哈希表中 key 对应的值列表
        }
        // 返回哈希表中的值列表,即为分组后的字母异位词列表
        return new ArrayList<List<String>>(map.values());
    }
}
最长连续序列(可用双指针,力扣题号128)

给出一个乱序数组,要求找出 最长连续序列(即找出前一个比后一个大1的最长序列)

class Solution {
    public int longestConsecutive(int[] nums) {
       if (nums.length == 0) return 0;
        Set<Integer> set = new HashSet<>();
        for (int num : nums) {
            set.add(num);
        }
        int max = 0;
        for (int num : set) {
            // 跳过所有可能的起始数字
            if (set.contains(num - 1)) continue;
            int count = 1;
            while (set.contains(num + 1)) {
                num += 1;
                count += 1;
            }
            max = Math.max(max, count);
        }
        return max;
    }
}

双指针

利用  l 、r(或 i 、j ) 两个指针对字符串、数组等元素操作问题进行解题

 最长连续序列(可用哈希,力扣题号128)

给出一个乱序数组,要求找出 最长连续序列(即找出前一个比后一个大1的最长序列)

class Solution {
    public int longestConsecutive(int[] nums) {
        if(nums.length == 0) return 0;
        // 对数组排序
        Arrays.sort(nums);
        int max = 1;
        int count = 1;
        int i = 0;
        // 双指针去重
        for (int j = 1; j < nums.length; ++j) {
            // 如果重复,跳过
            if (nums[i] == nums[j]) {
                continue;
            } else if (nums[i] + 1 == nums[j]) {
                count++;
                max = Math.max(max, count);
            } else {
                count = 1;
            }
            // 更新慢指针
            i = j;
        }
        return max;
    }
}
移动零(力扣题号283)

将数组中的零移到末尾,其他顺序不变

class Solution {
    public void moveZeroes(int[] nums) {
        //l是慢指针
        int l = 0;
        //r是快指针
        for (int r = 0; r < nums.length; r++) {
            if (nums[r] != 0) {
                //先进行复制再l+1
                nums[l++] = nums[r];
            }
        }
        //补零
        while(l < nums.length){
            nums[l++] = 0;
        }
    }
}
盛水最多的容器(经典,力扣题号11) 

面积 = 短边 * 两边距离之差

class Solution {
    public int maxArea(int[] height) {
        int l = 0;
        int r = height.length - 1;
        int x = 0;
        while(l < r){
            int t = (r - l) * Math.min(height[l], height[r]);
            x = Math.max(x, t);
            if(height[l] < height[r]){
                l++;
            }else{
                r--;
            }
        }
        return x;
    }
}
三数之和(力扣题号15) 

双指针 l,r ,在遍历过程中双指针不断变化来查找合适数组,难点在于去重

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> list = new ArrayList<>();
        Arrays.sort(nums);

        for (int i = 0; i < nums.length - 2; i++) {
            // 跳过重复的元素
            if (i > 0 && nums[i] == nums[i - 1]) continue;
            int l = i + 1, r = nums.length - 1;
            while (l < r) {
                int sum = nums[i] + nums[l] + nums[r];
                // 如果当前和等于0,则添加当前三元组到结果列表中
                if (sum == 0) {
                    list.add(Arrays.asList(nums[i], nums[l], nums[r]));
                    // 跳过所有重复的元素,以避免重复的三元组
                    while (l < r && nums[l] == nums[l + 1]) l++;
                    while (l < r && nums[r] == nums[r - 1]) r--;
                    l++;
                    r--;
                }
                // 如果当前和小于0,则移动左指针
                else if (sum < 0) l++;
                // 如果当前和大于0,则移动右指针
                else r--;
            }
        }
        return list;
    }
}

  • 11
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值