Leetcode(经典题)day2

H指数

274. H 指数 - 力扣(LeetCode)

先对数组排序,然后从大的一头开始遍历,只要数组当前的数比现在的h指数大就给h指数+1,直到数组当前的数比现在的h指数小的时候结束,这时h的值就是要返回的结果。

|-----|---|---|---|---|---|
| 排序前 | 3 | 0 | 6 | 1 | 5 |
| 排序后 | 0 | 1 | 3 | 5 | 6 |
| h值 | # | # | 3 | 2 | 1 |

    public int hIndex(int[] citations) {
        Arrays.sort(citations);
        int i = citations.length-1;
        int h = 0;
        while(i>=0&&citations[i]>h){
            h++;
            i--;
        }
        return h;
    }

O(1) 时间插入、删除和获取随机元素

380. O(1) 时间插入、删除和获取随机元素 - 力扣(LeetCode)

通过一个map和一个数组来实现

插入:map<Integer,Integer> (<值,在数组的下标>) list存值

删除:不光需要将目标值删除,还需要将删除后空出来的地方进行填补,不然后面的获取随机元素会出错。填补流程如下。

class RandomizedSet {

    private Map<Integer,Integer> map ;
    private List<Integer> list;

    public RandomizedSet() {
        map = new HashMap<>();
        list = new ArrayList<>();
    }

    public boolean insert(int val) {
        if(map.containsKey(val)){
            return false;
        }
        map.put(val,list.size());
        list.add(val);
        return true;
    }

    public boolean remove(int val) {
        if(!map.containsKey(val)){
            return false;
        }
        int a = map.get(val);
        int last = list.get(list.size()-1);
        list.set(a,last);
        
        map.put(last,a);
        list.remove(list.size()-1);
        map.remove(val);
        return true;
    }

    public int getRandom() {
        Random random = new Random();
        int randomNumber = random.nextInt(list.size());
        return list.get(randomNumber);
    }
}

除自身以外数组的乘积

238. 除自身以外数组的乘积 - 力扣(LeetCode)

要求时间复杂度为O(N),且不能用除法,所以我们可以进行两次遍历,第一次遍历将每个位置左边的所有数的乘积计算出来,第二次遍历把每个位置右边的所有数的乘积计算出来,最后相乘即可。

public static int[] productExceptSelf(int[] nums) {
        int n = nums.length;
        int[] arr1 = new int[n];
        int[] arr2 = new int[n];
        int res = 0;
        arr1[0] = 1;
        arr2[n-1] = 1;
        for (int i = 1; i < n; i++) {
            arr1[i]=arr1[i-1]*nums[i-1];
        }
        // System.out.println(Arrays.toString(arr1));
        for (int i = n-2; i >= 0; i--) {
            arr2[i]=arr2[i+1]*nums[i+1];
        }
        // System.out.println(Arrays.toString(arr2));
        for (int i = 0; i < n; i++) {
            nums[i]=arr1[i]*arr2[i];
        }
        return nums;
    }

加油站

主要的两个变量,left(记录当前剩余的汽油量,用来判断起始点),sum(记录总油量是否大于耗油量),每当left<0时,则说明前边的节点都不可用,让现在节点的下一个节点作为新的起始点,并将当前剩余油量left重置为0,遍历完数组,判断sum是否小于0,是则返回-1,不是则返回现在的起始节点。

    public int canCompleteCircuit(int[] gas, int[] cost) {
        int n = gas.length;
        int left = 0;
        int sum = 0;
        int index = 0;
        for (int i = 0,p; i < n; i++) {
            p = gas[i]-cost[i];
            left += p;
            sum += p;
            if(left<0){
                left = 0;
                index = i+1;
            }
        }
        return sum < 0 ? -1 : index;
    }

罗马数字转整数

先写一个获取对应的字符值的方法,然后找一个变量记录前一个字符对应的值,每次比较当前字符的值与前一个字符的值的大小,分为两种情况,当前>之前,则是类似于"IV",则结果应该减去前一个字符对应值,若当前<=之前,则对应的是类似于"II"或者"VI",则应该加上前一个字符对应值,最后不要忘记加上最后一个字符的值。

public static int romanToInt(String s) {
        int res = 0;
        int pre = 0;
        pre = getnumber(s.charAt(0));
        int n = s.length();
        for (int i = 1; i < n; i++) {
            int index = getnumber(s.charAt(i));
            if (pre<index){
                res-=pre;
            }else{
                res+=pre;
            }
            pre = index;
        }
        res += pre;
        return res;
    }

    public static int getnumber(char ch){
        switch (ch){
            case 'I': return 1;
            case 'V': return 5;
            case 'X': return 10;
            case 'L': return 50;
            case 'C': return 100;
            case 'D': return 500;
            case 'M': return 1000;
            default: return 0;
        }
    }

整数转罗马数字

12. 整数转罗马数字 - 力扣(LeetCode)

这个没什么说的,直接看代码就好了。

public String intToRoman(int num) {
        StringBuilder str = new StringBuilder();
        while(num>=1000){
            str.append("M");
            num-=1000;
        }
        if (num>=900){
            str.append("CM");
            num-=900;
        }
        if (num>=500){
            str.append("D");
            num-=500;
        }
        if (num>=400){
            str.append("CD");
            num-=400;
        }
        while (num>=100){
            str.append("C");
            num-=100;
        }
        if (num>=90){
            str.append("XC");
            num-=90;
        }
        if (num>=50){
            str.append("L");
            num-=50;
        }
        if (num>=40){
            str.append("XL");
            num-=40;
        }
        while (num>=10){
            str.append("X");
            num-=10;
        }
        if (num>=9){
            str.append("IX");
            num-=9;
        }
        if (num>=5){
            str.append("V");
            num-=5;
        }
        if (num>=4){
            str.append("IV");
            num-=4;
        }
        while (num>=1){
            str.append("I");
            num-=1;
        }
        return str.toString();
    }

最后一个单词的长度

58. 最后一个单词的长度 - 力扣(LeetCode)

第一次循环找到不为' '的起点,第二次循环第一次遇到' '停止。

    public int lengthOfLastWord(String s) {
        int count = 0;
        int index = s.length()-1;
        while (s.charAt(index)==' '){
            index--;
        }
        while (index>=0&&s.charAt(index)!=' '){
            index--;
            count++;
        }
        return count;
    }

最长公共前缀

14. 最长公共前缀 - 力扣(LeetCode)

将第一个字符串当作公共前缀,对每个字符串进行匹配判断,如果与当前公共前缀不符,则将公共前缀长度-1,循环判断,直到当前公共前缀符合或者公共前缀长度为0。

    public String longestCommonPrefix(String[] strs) {
        if (strs==null||strs.length==0) {
            return "";
        }
        String pre = strs[0];
        for (int i = 1; i < strs.length; i++) {
            while (strs[i].indexOf(pre) !=0){
                pre = pre.substring(0,pre.length()-1);
                if (pre.length()==0){
                    return "";
                }
            }
        }
        return pre;
    }

翻转字符串中的单词

151. 反转字符串中的单词 - 力扣(LeetCode)

从后向前遍历,使用双指针来确定单词的范围。

    public static String reverseWords(String s) {
        StringBuilder str = new StringBuilder();
        s = s.trim();
        int n = s.length();
        int l = n-1;
        int r = n-1;
        while (l>=0){
            while (l>=0&&s.charAt(l)!=' '){
                l--;
            }
            str.append(s.substring(l+1,r+1)+" ");
            while (l>=0&&s.charAt(l)==' '){
                l--;
            }
            r=l;
        }
        return str.toString().trim();
    }

找出字符串中第一个匹配项的下标

28. 找出字符串中第一个匹配项的下标 - 力扣(LeetCode)

直接暴力解决吧,想提升可以使用KPM

    public int strStr(String haystack, String needle) {
        int n = haystack.length(), m = needle.length();
        for (int i = 0; i + m <= n; i++) {
            boolean flag = true;
            for (int j = 0; j < m; j++) {
                if (haystack.charAt(i + j) != needle.charAt(j)) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                return i;
            }
        }
        return -1;
    }

Z字形态变换

6. Z 字形变换 - 力扣(LeetCode)

使用列表,将每一行的字符加入自己所在行对应的字符串中,用一个标志量来确定方向,到头就转向。

    public String convert(String s, int numRows) {
        if(numRows < 2) return s;
        List<StringBuilder> rows = new ArrayList<StringBuilder>();
        for(int i = 0; i < numRows; i++) rows.add(new StringBuilder());
        int i = 0, flag = -1;
        for(char c : s.toCharArray()) {
            rows.get(i).append(c);
            if(i == 0 || i == numRows -1) flag = - flag;
            i += flag;
        }
        StringBuilder res = new StringBuilder();
        for(StringBuilder row : rows) res.append(row);
        return res.toString();
    }
相关推荐
CV工程师小林36 分钟前
【算法】BFS 系列之边权为 1 的最短路问题
数据结构·c++·算法·leetcode·宽度优先
天玑y2 小时前
算法设计与分析(背包问题
c++·经验分享·笔记·学习·算法·leetcode·蓝桥杯
sjsjs112 小时前
【数据结构-一维差分】力扣1893. 检查是否区域内所有整数都被覆盖
数据结构·算法·leetcode
m0_571957582 小时前
Java | Leetcode Java题解之第406题根据身高重建队列
java·leetcode·题解
山脚ice2 小时前
【Hot100】LeetCode—72. 编辑距离
算法·leetcode
鱼跃鹰飞3 小时前
Leetcode面试经典150题-349.两个数组的交集
算法·leetcode·面试
大二转专业4 小时前
408算法题leetcode--第七天
考研·算法·leetcode
戊子仲秋7 小时前
【LeetCode】每日一题 2024_9_19 最长的字母序连续子字符串的长度(字符串,双指针)
算法·leetcode·职场和发展
程序猿练习生10 小时前
C++速通LeetCode中等第5题-无重复字符的最长字串
开发语言·c++·leetcode
MogulNemenis12 小时前
力扣150题——位运算
数据结构·算法·leetcode