LeetCode 11-15 题 详解 Java版 ( 万字 图文详解 LeetCode 算法题11-15 =====>>> <建议收藏>)

简介: LeetCode 11-15 题 详解 Java版 ( 万字 图文详解 LeetCode 算法题11-15 =====>>> <建议收藏>)

目录


第11题. Container With Most Water

题目描述(中等难度)

解法一 暴力解法

解法二

第12题. Integer to Roman

题目描述(中等难度)

解法一

解法二

解法三

第13题: Roman to Integer

题目描述(简单难度)

解法一

解法二

解法三

第14题: Longest Common Prefix

解法一 垂直比较

解法二 水平比较

解法三 递归

第15题 : 3Sum

题目描述(中等难度)

解法一 暴力解法

解法二

喜欢 请点个 + 关注



第11题. Container With Most Water

题目描述(中等难度)


2.jpg


每个数组代表一个高度,选两个任意的柱子往里边倒水,能最多倒多少水。


解法一 暴力解法

直接遍历任意两根柱子,求出能存水的大小,用一个变量保存最大的。

public int maxArea(int[] height) {
    int max = 0;
    for (int i = 0; i < height.length; i++) {
        for (int j = i + 1; j < height.length; j++) {
            int h = Math.min(height[i], height[j]);
            if (h * (j - i) > max) {
                max = h * (j - i);
            }
        }
    }
    return max;
}

时间复杂度:O(n²)。

空间复杂度:O(1)。


解法二


3.jpg

我们理一下思路,大小是由长度和高度决定,如果选 0 到 8 就保证了长度最长,此时大小是 0 号柱子的高度 1 乘以长度 8 。我们如果想面积更大怎么做呢,只能减小长度,增加高度。是左边的柱子向右移动变成 1 号柱子呢?还是右边的柱子向左移动变成 7 号柱子呢?当然是哪边的柱子短就改哪边的!只有这样,高度才有可能增加。


例如我们如果把 8 号柱子变成 7 号柱子,此时长度减少了,然而高度还是 0 号柱子没有变化,所以面积就会减少。把 1 号柱子变成 2 号柱子就很好了,因为此时高度就变成了 8 号柱子的高度,面积就有可能会增加。


如果左右两边柱子相等该怎么办呢?随意!


我们假设 1 号 和 8 号 柱子高度是相等的。如果他们之间的柱子只有 1 根比它俩高或者没有比它俩高的,那么最大面积就一定选取是 1 号和 8 号了,所以 1 号接着变大,或者 8 号接着减小都是无所谓的,因为答案已经确定了。


44.jpg

假设 1 号 和 8 号之间有 2 根或以上的柱子比它俩高,假设是 4 号和 6 号比它俩高。1 号会变到 2 号、3 号,最终为 4 号,8 号会变到 7 号, 6 号,而在这个过程中产生的面积一定不会比 1 号和 8 号产生的面积大,因为过程中的柱子都比 1 号和 8 号低。所以是先变 1 号还是先变 8 号是无所谓的,无非是谁先到达更长的柱子而已。


看一下下边的算法,会更加清楚一些。

public int maxArea2(int[] height) {
    int maxarea = 0, l = 0, r = height.length - 1;
    while (l < r) {
        maxarea = Math.max(maxarea, Math.min(height[l], height[r]) * (r - l));
        if (height[l] < height[r])
            l++;
        else
            r--;
    }
    return maxarea;
}

时间复杂度:O(n)。

空间复杂度:O(1)。


为了减少暴力解法的时间复杂度,只能去深层次的理解题意,从而找出突破点。


第12题. Integer to Roman

题目描述(中等难度)


5.jpg

把数字转换成罗马数字,正常情况就是把每个字母相加,并且大字母在前,小字母在后,上边也介绍了像 4 和 9 那些特殊情况。


解法一

这个是自己的解法,主要思想就是每次取出一位,然后得到相应的罗马数字,然后合起来就行


public String getRoman(int num,int count){ //count 表示当前的位数,个位,十位...
    char[]ten={'I','X','C','M'}; //1,10,100,1000
    char[]five={'V','L','D'};//5,50,500
    String r="";
    if(num<=3){
        while(num!=0){
            r+=ten[count];
            num--;
        }
    }
    if(num==4){
        r=(ten[count]+"")+(five[count]+"");
    }
    if(num==5){
        r=five[count]+"";
    }
    if(num>5&&num<9){
        r=five[count]+"";
        num-=5;
        while(num!=0){
            r+=ten[count];
            num--;
        }
    }
    if(num==9){
        r = (ten[count] + "") + (ten[count + 1] + "");
    }
    return r;
}
public String intToRoman(int num) {
    String r="";
    int count=0;
    while(num!=0){
        int pop=num%10;
        r=getRoman(pop,count)+r;
        count++;
        num/=10;
    }
    return r;
}


时间复杂度:num 的位数 log10(num)+1log_{10}(num)+1log10(num)+1所以时间复杂度是 O(log(n))。

空间复杂度:常数个变量,O(1)。

下边在分享一些 LeetCode 讨论里的一些解法


解法二

https://leetcode.com/problems/integer-to-roman/discuss/6310/My-java-solution-easy-to-understand

public String intToRoman(int num) {
    int[] values = {1000,900,500,400,100,90,50,40,10,9,5,4,1};
    String[] strs = {"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
    StringBuilder sb = new StringBuilder();
    for(int i=0;i<values.length;i++) {
        while(num >= values[i]) {
            num -= values[i];
            sb.append(strs[i]);
        }
    }
    return sb.toString();
}

相当简洁了,主要就是把所有的组合列出来,因为罗马数字表示的大小就是把所有字母相加,所以每次 append 那个,再把对应的值减去就行了。

时间复杂度:不是很清楚,也许是 O(1)?因为似乎和问题规模没什么关系了。

空间复杂度:O(1).


解法三

https://leetcode.com/problems/integer-to-roman/discuss/6376/Simple-JAVA-solution


public String intToRoman(int num) {
    String M[] = {"", "M", "MM", "MMM"};//0,1000,2000,3000
    String C[] = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};//0,100,200,300...
    String X[] = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};//0,10,20,30...
    String I[] = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};//0,1,2,3...
    return M[num/1000] + C[(num%1000)/100]+ X[(num%100)/10] + I[num%10];
}


这就更加暴力了,把每位的情况都列出来然后直接返回,但思路清晰明了呀。

时间复杂度:O(1)或者说是 num 的位数,不是很确定。

空间复杂度:O(1)。


这道题感觉难度应该是 easy ,没有那么难,就是理清楚题意,然后就可以往出列举就行了。


第13题: Roman to Integer

题目描述(简单难度)

66.jpg


和上一道题相反,将罗马数字转换成阿拉伯数字。


解法一

先来一种不优雅的,也就是我开始的想法。就是遍历字符串,然后转换就可以,但同时得考虑 IV,IX 那些特殊情况。

public int getInt(char r) {
        int ans = 0;
        switch (r) {
        case 'I':
            ans = 1;
            break;
        case 'V':
            ans = 5;
            break;
        case 'X':
            ans = 10;
            break;
        case 'L':
            ans = 50;
            break;
        case 'C':
            ans = 100;
            break;
        case 'D':
            ans = 500;
            break;
        case 'M':
            ans = 1000;
        }
        return ans;
    }
    public int getInt(char r, char r_after) {
        int ans = 0;
        switch (r) {
        case 'I':
            ans = 1;
            break;
        case 'V':
            ans = 5;
            break;
        case 'X':
            ans = 10;
            break;
        case 'L':
            ans = 50;
            break;
        case 'C':
            ans = 100;
            break;
        case 'D':
            ans = 500;
            break;
        case 'M':
            ans = 1000;
            break;
        }
        if (r == 'I') {
            switch (r_after) {
            case 'V':
                ans = 4;
                break;
            case 'X':
                ans = 9;
            }
        }
        if (r == 'X') {
            switch (r_after) {
            case 'L':
                ans = 40;
                break;
            case 'C':
                ans = 90;
            }
        }
        if (r == 'C') {
            switch (r_after) {
            case 'D':
                ans = 400;
                break;
            case 'M':
                ans = 900;
            }
        }
        return ans;
    }
    public boolean isGetTwoInt(char r, char r_after) {
        if (r == 'I') {
            switch (r_after) {
            case 'V':
                return true;
            case 'X':
                return true;
            }
        }
        if (r == 'X') {
            switch (r_after) {
            case 'L':
                return true;
            case 'C':
                return true;
            }
        }
        if (r == 'C') {
            switch (r_after) {
            case 'D':
                return true;
            case 'M':
                return true;
            }
        }
        return false;
    }
    public int romanToInt(String s) {
        int ans = 0;
        for (int i = 0; i < s.length() - 1; i++) {
            ans += getInt(s.charAt(i), s.charAt(i + 1));
            //判断是否是两个字符的特殊情况
            if (isGetTwoInt(s.charAt(i), s.charAt(i + 1))) {
                i++;
            }
        }
        //将最后一个字符单独判断,如果放到上边的循环会越界
        if (!(s.length() >= 2 && isGetTwoInt(s.charAt(s.length() - 2), s.charAt(s.length() - 1)))) {
            ans += getInt(s.charAt(s.length() - 1));
        }
        return ans;
    }


时间复杂度:O(n),n 是字符串的长度。

空间复杂度:O(1)。

下边分享一些优雅的。


解法二

https://leetcode.com/problems/roman-to-integer/description/


public int romanToInt(String s) {
     int sum=0;
    if(s.indexOf("IV")!=-1){sum-=2;}
    if(s.indexOf("IX")!=-1){sum-=2;}
    if(s.indexOf("XL")!=-1){sum-=20;}
    if(s.indexOf("XC")!=-1){sum-=20;}
    if(s.indexOf("CD")!=-1){sum-=200;}
    if(s.indexOf("CM")!=-1){sum-=200;}
    char c[]=s.toCharArray();
    int count=0;
   for(;count<=s.length()-1;count++){
       if(c[count]=='M') sum+=1000;
       if(c[count]=='D') sum+=500;
       if(c[count]=='C') sum+=100;
       if(c[count]=='L') sum+=50;
       if(c[count]=='X') sum+=10;
       if(c[count]=='V') sum+=5;
       if(c[count]=='I') sum+=1;
   }
   return sum;
}


把出现的特殊情况,提前减了就可以。

时间复杂度:O(1)。

空间复杂度:O(1


解法三

https://leetcode.com/problems/roman-to-integer/discuss/6509/7ms-solution-in-Java.-easy-to-understand


利用到罗马数字的规则,一般情况是表示数字大的字母在前,数字小的字母在后,如果不是这样,就说明出现了特殊情况,此时应该做减法。


 private int getVal(char c){
        switch (c){
            case 'M':
                return 1000;
            case 'D':
                return 500;
            case 'C':
                return 100;
            case 'L':
                return 50;
            case 'X' :
                return 10;
            case 'V':
                return 5;
            case 'I':
                return 1;
        }
        throw new IllegalArgumentException("unsupported character");
    }
    public int romanToInt(String s) {
        int res = 0;
        if(s.length() == 0) return res;
        for (int i = 0; i < s.length() - 1; i++) {
            int cur = getVal(s.charAt(i));
            int nex = getVal(s.charAt(i+1));
            if(cur < nex){
                res -= cur;
            }else{
                res += cur;
            }
        }
        return res + getVal(s.charAt(s.length()-1));
    }


时间复杂度:O(1)。

空间复杂度:O(1)


这道题也不难,自己一开始没有充分利用罗马数字的特点,而是用一些 if,switch 语句判断是否是特殊情况,看起来就很繁琐了。


第14题: Longest Common Prefix


8.jpg


解法一 垂直比较


9.jpg

我们把所有字符串垂直排列,然后一列一列的比较,直到某一个字符串到达结尾或者该列字符不完全相同。

下边看一下我的代码,看起来比较多


//这个函数判断 index 列的字符是否完全相同
public boolean isSameAtIndex(String[] strs, int index) {
    int i = 0;
    while (i < strs.length - 1) {
        if (strs[i].charAt(index) == strs[i + 1].charAt(index)) {
            i++;
        } else {
            return false;
        }
    }
    return true;
}
public String longestCommonPrefix(String[] strs) {
    if (strs.length == 0)
        return "";
    //得到最短的字符串的长度
    int minLength = Integer.MAX_VALUE;
    for (int i = 0; i < strs.length; i++) {
        if (strs[i].length() < minLength) {
            minLength = strs[i].length();
        }
    }
    int j = 0;
    //遍历所有列
    for (; j < minLength; j++) {
        //如果当前列字符不完全相同,则结束循环
        if (!isSameAtIndex(strs, j)) {
            break;
        }
    }
    return strs[0].substring(0, j);
}

下边看一下,官方的代码

public String longestCommonPrefix(String[] strs) {
    if (strs == null || strs.length == 0) return "";
    //遍历所有列
    for (int i = 0; i < strs[0].length() ; i++){
        char c = strs[0].charAt(i); // 保存 i 列第 0 行的字符便于后续比较
        //比较第 1,2,3... 行的字符和第 0 行是否相等
        for (int j = 1; j < strs.length; j ++) {
            /**
             * i == strs[j].length() 表明当前行已经到达末尾
             * strs[j].charAt(i) != c  当前行和第 0 行字符不相等
             * 上边两种情况返回结果
             */
            if (i == strs[j].length() || strs[j].charAt(i) != c)
                return strs[0].substring(0, i);             
        }
    }
    return strs[0];
}


时间复杂度:最坏的情况就是 n 个 长度为 m 的完全一样的字符串,假设 S 是所有字符的和,那么 S = m * n,时间复杂度就是 O(S)。当然正常情况下并不需要比较所有字符串,最多比较 n * minLen 个字符就可以了。

空间复杂度:O(1),常数个额外空间。


解法二 水平比较


10.jpg

我们将字符串水平排列,第 0 个和第 1 个字符串找最长子串,结果为 leet,再把结果和第 2 个字符串比较,结果为 leet,再把结果和第 3 个字符串比较,结果为 lee,即为最终结果。

public String longestCommonPrefix3(String[] strs) {
        if (strs.length == 0)
            return "";
        String prefix = strs[0]; // 保存结果
        // 遍历每一个字符串
        for (int i = 1; i < strs.length; i++) {
            // 找到上次得到的结果 prefix 和当前字符串的最长子串
            int minLen = Math.min(prefix.length(), strs[i].length());
            int j = 0;
            for (; j < minLen; j++) {
                if (prefix.charAt(j) != strs[i].charAt(j)) {
                    break;
                }
            }
            prefix = prefix.substring(0, j);
        }
        return prefix;
    }


时间复杂度:最坏情况和解法一是一样,n 个长度为 m 的完全相同的字符,就要比较所有的字符 S,S = n * m 。但对于正常情况,处于最短字符串前的字符串依旧要比较所有字符,而不是最短字符串个字符,相对于解法一较差。

空间复杂度:O(1)。


解法三 递归11.jpg


我们把原来的数组分成两部分,求出左半部分的最长公共前缀,求出右半部分的最长公共前缀,然后求出的两个结果再求最长公共前缀,就是最后的结果了。


求左半部分的最长公共前缀,我们可以继续把它分成两部分,按照上边的思路接着求。然后一直分成两部分,递归下去。


直到该部分只有 1 个字符串,那么最长公共子串就是它本身了,直接返回就可以了。

public String longestCommonPrefix(String[] strs) {
    if (strs == null || strs.length == 0) return "";    
        return longestCommonPrefix(strs, 0 , strs.length - 1);
}
//递归不断分成两部分
private String longestCommonPrefix(String[] strs, int l, int r) {
    if (l == r) {
        return strs[l];
    }
    else {
        int mid = (l + r)/2;
        String lcpLeft =   longestCommonPrefix(strs, l , mid);
        String lcpRight =  longestCommonPrefix(strs, mid + 1,r);
        return commonPrefix(lcpLeft, lcpRight);
   }
}
//求两个结果的最长公共前缀
String commonPrefix(String left,String right) {
    int min = Math.min(left.length(), right.length());       
    for (int i = 0; i < min; i++) {
        if ( left.charAt(i) != right.charAt(i) )
            return left.substring(0, i);
    }
    return left.substring(0, min);
}


时间复杂度:

空间复杂度:

每次遇到递归的情况,总是有些理不清楚,先空着吧。


进行了垂直比较和水平比较,又用到了递归,solution 里还介绍了二分查找,感觉这里用二分查找有些太僵硬了,反而使得时间复杂度变高了。还介绍了前缀树,这里后边遇到再总结吧。


第15题 : 3Sum

题目描述(中等难度)


12.jpg

解法一 暴力解法

无脑搜索,三层循环,遍历所有的情况。但需要注意的是,我们需要把重复的情况去除掉,就是 [1, -1 ,0] 和 [0, -1, 1] 是属于同一种情况的。


public List<List<Integer>> threeSum(int[] nums) {
    List<List<Integer>> res = new ArrayList<List<Integer>>();
    for (int i = 0; i < nums.length; i++) {
        for (int j = i + 1; j < nums.length; j++)
            for (int k = j + 1; k < nums.length; k++) {
                if (nums[i] + nums[j] + nums[k] == 0) {
                    List<Integer> temp = new ArrayList<Integer>();
                    temp.add(nums[i]);
                    temp.add(nums[j]);
                    temp.add(nums[k]); 
                    //判断结果中是否已经有 temp 。
                    if (isInList(res, temp)) {
                        continue;
                    }
                    res.add(temp);
                }
            }
    }
    return res;
}
public boolean isInList(List<List<Integer>> l, List<Integer> a) {
    for (int i = 0; i < l.size(); i++) {
        //判断两个 List 是否相同
        if (isSame(l.get(i), a)) {
            return true;
        }
    }
    return false;
}
public boolean isSame(List<Integer> a, List<Integer> b) {
    int count = 0;
    Collections.sort(a);
    Collections.sort(b);
    //排序后判断每个元素是否对应相等
    for (int i = 0; i < a.size(); i++) {
        if (a.get(i) != b.get(i)) {
            return false;
        }
    }
    return true;
}


时间复杂度:n 表示 num 的个数,三个循环 O(n³),而 isInList 也需要 O(n),总共就是 O(n4)O(n^4)O(n4),leetCode 复杂度到了 O(n3)O(n^3)O(n3) 一般就报超时错误了,所以算法还得优化。


空间复杂度:最坏情况,即 O(N), N 是指 n 个元素的排列组合个数,即 N=Cn3N=C^3_nN=Cn3,用来保存结果。


解法二


参考了这里


主要思想是,遍历数组,用 0 减去当前的数,作为 sum ,然后再找两个数使得和为 sum。


这样看来遍历需要 O(n),再找两个数需要 O(n²)的复杂度,还是需要 O(n³)。


巧妙之处在于怎么找另外两个数。


最最优美的地方就是,首先将给定的 num 排序。


这样我们就可以用两个指针,一个指向头,一个指向尾,去找这两个数字,这样的话,找另外两个数时间复杂度就会从 O(n²),降到 O(n)。


而怎么保证不加入重复的 list 呢?


要记得我们的 nums 已经有序了,所以只需要找到一组之后,当前指针要移到和当前元素不同的地方。其次在遍历数组的时候,如果和上个数字相同,也要继续后移。文字表述比较困难,可以先看下代码。


public List<List<Integer>> threeSum(int[] num) {
    Arrays.sort(num); //排序
    List<List<Integer>> res = new LinkedList<>(); 
    for (int i = 0; i < num.length-2; i++) {
        //为了保证不加入重复的 list,因为是有序的,所以如果和前一个元素相同,只需要继续后移就可以
        if (i == 0 || (i > 0 && num[i] != num[i-1])) {
            //两个指针,并且头指针从i + 1开始,防止加入重复的元素
            int lo = i+1, hi = num.length-1, sum = 0 - num[i];
            while (lo < hi) {
                if (num[lo] + num[hi] == sum) {
                    res.add(Arrays.asList(num[i], num[lo], num[hi]));
                    //元素相同要后移,防止加入重复的 list
                    while (lo < hi && num[lo] == num[lo+1]) lo++;
                    while (lo < hi && num[hi] == num[hi-1]) hi--;
                    lo++; hi--;
                } else if (num[lo] + num[hi] < sum) lo++;
                else hi--;
           }
        }
    }
    return res;
}


时间复杂度:O(n²),n 指的是 num

空间复杂度:O(N),最坏情况,即 N 是指 n 个元素的排列组合个数,即 N=Cn3N=C^3_nN=Cn3,用来保存结果。


对于遍历,这里用到了从两头同时遍历,从而降低了时间复杂度,很妙!

今天我们一起学习了LeetCode 10-15 题的算法分析,感谢大家阅读,觉得不错记得收藏哦!

喜欢 请点个 + 关注

目录
打赏
0
0
0
0
736
分享
相关文章
Java 实现局域网电脑屏幕监控算法揭秘
在数字化办公环境中,局域网电脑屏幕监控至关重要。本文介绍用Java实现这一功能的算法,涵盖图像采集、数据传输和监控端显示三个关键环节。通过Java的AWT/Swing库和Robot类抓取屏幕图像,使用Socket进行TCP/IP通信传输图像数据,并利用ImageIO类在监控端展示图像。整个过程确保高效、实时和准确,为提升数字化管理提供了技术基础。
116 15
探究‘公司禁用 U 盘’背后的哈希表算法与 Java 实现
在数字化办公时代,信息安全至关重要。许多公司采取“禁用U盘”策略,利用哈希表算法高效管理外接设备的接入权限。哈希表通过哈希函数将设备标识映射到数组索引,快速判断U盘是否授权。例如,公司预先将允许的U盘标识存入哈希表,新设备接入时迅速验证,未授权则禁止传输并报警。这有效防止恶意软件和数据泄露,保障企业信息安全。 代码示例展示了如何用Java实现简单的哈希表,模拟公司U盘管控场景。哈希表不仅用于设备管理,还在文件索引、用户权限等多方面助力信息安全防线的构建,为企业数字化进程保驾护航。
解锁“分享文件”高效密码:探秘 Java 二叉搜索树算法
在信息爆炸的时代,文件分享至关重要。二叉搜索树(BST)以其高效的查找性能,为文件分享优化提供了新路径。本文聚焦Java环境下BST的应用,介绍其基础结构、实现示例及进阶优化。BST通过有序节点快速定位文件,结合自平衡树、多线程和权限管理,大幅提升文件分享效率与安全性。代码示例展示了文件插入与查找的基本操作,适用于大规模并发场景,确保分享过程流畅高效。掌握BST算法,助力文件分享创新发展。
解锁分布式文件分享的 Java 一致性哈希算法密码
在数字化时代,文件分享成为信息传播与协同办公的关键环节。本文深入探讨基于Java的一致性哈希算法,该算法通过引入虚拟节点和环形哈希空间,解决了传统哈希算法在分布式存储中的“哈希雪崩”问题,确保文件分配稳定高效。文章还展示了Java实现代码,并展望了其在未来文件分享技术中的应用前景,如结合AI优化节点布局和区块链增强数据安全。
企业局域网监控软件中 Java 优先队列算法的核心优势
企业局域网监控软件是数字化时代企业网络安全与高效运营的基石,犹如一位洞察秋毫的卫士。通过Java实现的优先队列算法,它能依据事件优先级排序,确保关键网络事件如异常流量、数据泄露等被优先处理,保障系统稳定与安全。代码示例展示了如何定义网络事件类并使用PriorityQueue处理高优先级事件,尤其在面对疑似风险时迅速启动应急措施。这一核心技术助力企业在复杂网络环境中稳健前行,护航业务腾飞。
78 32
Java线程调度揭秘:从算法到策略,让你面试稳赢!
在社招面试中,关于线程调度和同步的相关问题常常让人感到棘手。今天,我们将深入解析Java中的线程调度算法、调度策略,探讨线程调度器、时间分片的工作原理,并带你了解常见的线程同步方法。让我们一起破解这些面试难题,提升你的Java并发编程技能!
138 16
剖析基于Java算法驱动的智能局域网管控之道
本文探讨了基于Java语言的局域网控制方案,结合链表数据结构与令牌桶算法,解决设备管理和流量调度难题。通过链表灵活存储网络设备信息,实现高效设备管理;令牌桶算法则精准控制流量,确保网络平稳运行。二者相辅相成,为校园、企业等局域网提供稳固高效的控制体系,保障业务连续性和数据安全。
【潜意识Java】深度解析黑马项目《苍穹外卖》与蓝桥杯算法的结合问题
本文探讨了如何将算法学习与实际项目相结合,以提升编程竞赛中的解题能力。通过《苍穹外卖》项目,介绍了订单配送路径规划(基于动态规划解决旅行商问题)和商品推荐系统(基于贪心算法)。这些实例不仅展示了算法在实际业务中的应用,还帮助读者更好地准备蓝桥杯等编程竞赛。结合具体代码实现和解析,文章详细说明了如何运用算法优化项目功能,提高解决问题的能力。
121 6
【潜意识Java】蓝桥杯算法有关的动态规划求解背包问题
本文介绍了经典的0/1背包问题及其动态规划解法。
106 5
探秘局域网桌面监控:深入剖析 Java 语言核心算法
在数字化办公时代,局域网桌面监控如同企业的“智慧鹰眼”,确保工作效率与数据安全。本文以Java为载体,揭示哈希表在监控中的关键应用。通过高效的数据结构和算法,哈希表能快速索引设备连接信息,大幅提升监控的时效性和响应速度。代码示例展示了如何用Java实现设备网络连接监控,结合未来技术如AI、大数据,展望更智能的监控体系,助力企业在数字化浪潮中稳健前行。