zoukankan      html  css  js  c++  java
  • C++/Java小白解Leetcode题,发现了知识盲区……

    我的博客园:https://www.cnblogs.com/chenzhenhong/p/14072684.html

    我的CSDN博客:https://blog.csdn.net/Charzous/article/details/110355827


    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
    本文链接:https://blog.csdn.net/Charzous/article/details/110355827

    一、初见LeetCode

    大一时候学习C++,根据课程一直在PTA平台做题目,数据结构和算法的作业题目也是在PTA。后来发现牛客网学习资源也很丰富,孤陋寡闻,前几个月在知道LeetCode这个平台,跟牛客网可以并称“程序员的左膀右臂”๑乛◡乛๑。虽然认识了LeetCode,但是一直挤出时间过来练练题,仰慕一下各位大佬的AC。今天就试了几道题,发现风格与PTA有很大不同,还需要不断去熟悉,别具风格的打题也挺有意思,通过几个简单题目,发现自己知识盲区,希望能够学习到更多!下面记录一下几个题目的思路解法。

    二、字符串中的单词数

    题目:

    统计字符串中的单词个数,这里的单词指的是连续的不是空格的字符。

    请注意,你可以假定字符串里不包括任何不可打印的字符。

    示例:

    1.  
      输入: "Hello, my name is John"
    2.  
      输出: 5
    3.  
      解释: 这里的单词是指连续的不是空格的字符,所以 "Hello," 算作 1 个单词。

    题解:

    class Solution {
        public int countSegments(String s) {
            int count=0;
            s=s.trim();
            if(s.equals(""))
                count=0;
            else
            {
                
                String[] word=s.trim().split("\s+");
                count=word.length;
            }
            return count;
        }
    }

    开始直接想到Java的函数,对这道题可以简单处理,容易解决。不过期间有几个注意点,就是处理连续空格和边界情况。

    后来尝试C++手写方法,效果更好:

    image.png

     思路:使用一个flag标识每个单词分界点,如果当前字符不是空格且它前一个为空格(即此处分隔单词边界),则计数新单词个数。

    class Solution {
    public:
        int countSegments(string s) {
            int flag=1,count=0;
            for(int i=0;i<s.length();i++)
            {
                if(s[i]!=' '&&flag) 
                {
                    count++;
                    flag=0;
                }    
                if(s[i]==' ')
                    flag=1;
            }
            return count;
        }
    };
    /*
    作者:lu-hai-pan-jiang
    链接:https://leetcode-cn.com/problems/number-of-segments-in-a-string/solution/jian-dan-zhi-jie-si-lu-ji-bai-100-by-lu-hai-pan-ji/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    */

    三、最富有客户的资产总量

    给你一个 m x n 的整数网格 accounts ,其中 accounts[i][j] 是第 i​​​​​ 位客户在第 j 家银行托管的资产数量。返回最富有客户所拥有的 资产总量 。

    客户的 资产总量 就是他们在各家银行托管的资产数量之和。最富有客户就是 资产总量 最大的客户。

    示例 1:

    输入:accounts = [[1,2,3],[3,2,1]]
    输出:6
    解释:
    第 1 位客户的资产总量 = 1 + 2 + 3 = 6
    第 2 位客户的资产总量 = 3 + 2 + 1 = 6
    两位客户都是最富有的,资产总量都是 6 ,所以返回 6 。


    示例 2:

    输入:accounts = [[1,5],[7,3],[3,5]]
    输出:10
    解释:
    第 1 位客户的资产总量 = 6
    第 2 位客户的资产总量 = 10 
    第 3 位客户的资产总量 = 8
    第 2 位客户是最富有的,资产总量是 10


    示例 3:

    输入:accounts = [[2,8,7],[7,1,3],[1,9,5]]
    输出:17

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/richest-customer-wealth
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    Hint:

    m == accounts.length
    n == accounts[i].length
    1 <= m, n <= 50
    1 <= accounts[i][j] <= 100

    这题目是签到题,思路直接简单。

    class Solution {
        public int maximumWealth(int[][] accounts) {
            int maxV=0;
            for(int i=0;i<accounts.length;i++)
            {
                int sum=0;
                for(int j=0;j<accounts[i].length;j++)
                    sum+=accounts[i][j];
                if(maxV<sum)
                    maxV=sum;
            }
            return maxV;
        
        }
    }

    四、三角形的最大周长

    给定由一些正数(代表长度)组成的数组 A,返回由其中三个长度组成的、面积不为零的三角形的最大周长。

    如果不能形成任何面积不为零的三角形,返回 0。

    示例 1:

    输入:[2,1,2]
    输出:5


    示例 2:

    输入:[1,2,1]
    输出:0


    示例 3:

    输入:[3,2,3,4]
    输出:10


    示例 4:

    输入:[3,6,2,3]
    输出:8
     

    提示:

    3 <= A.length <= 10000
    1 <= A[i] <= 10^6

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/largest-perimeter-triangle
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 

    思路:先将边长降序排列,从后往前扫描,贪心的思想,取得能够组成三角形的最大周长。

    C++版本:

    class Solution {
    public:
        int largestPerimeter(vector<int>& A) {
            sort(A.begin(),A.end());
            for(int i=A.size()-1;i>=2;i--)
            {
                if(A[i-2]+A[i-1]>A[i])
                    return A[i-2]+A[i-1]+A[i];
            }
            return 0;
        }
    };

    Java版本:运行用时更短,奇怪了(・。・)

    class Solution {
        public int largestPerimeter(int[] A) {
            Arrays.sort(A);
            for(int i=A.length-1;i>=2;i--)
            {
                if(A[i-2]+A[i-1]>A[i])
                    return A[i-2]+A[i-1]+A[i];
            }
            return 0;
        }
    }

    五、找出最具竞争力的子序列(中等难度)

    给你一个整数数组 nums 和一个正整数 k ,返回长度为 k 且最具 竞争力 的 nums 子序列。数组的子序列是从数组中删除一些元素(可能不删除元素)得到的序列。

    在子序列 a 和子序列 b 第一个不相同的位置上,如果 a 中的数字小于 b 中对应的数字,那么我们称子序列 a 比子序列 b(相同长度下)更具 竞争力 。 例如,[1,3,4] 比 [1,3,5] 更具竞争力,在第一个不相同的位置,也就是最后一个位置上, 4 小于 5 。

    示例 1:

    输入:nums = [3,5,2,6], k = 2
    输出:[2,6]
    解释:在所有可能的子序列集合 {[3,5], [3,2], [3,6], [5,2], [5,6], [2,6]} 中,[2,6] 最具竞争力。


    示例 2:

    输入:nums = [2,4,3,3,5,4,9,6], k = 4
    输出:[2,3,3,4]
     

    提示:

    1 <= nums.length <= 105
    0 <= nums[i] <= 109
    1 <= k <= nums.length

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/find-the-most-competitive-subsequence
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    前面几道属于简单类型,这道中等题目就显得有些分量了,题目需要琢磨一会才知道是要干啥,就题做题。

    看到一个大佬的解题思路,这个比较好理解:传送门

    维护一个单调栈,从左到右遍历数组。

    1、如果当前元素比队尾元素小,接下来判断剩余数组长度(len - i)和目标栈还需要元素个数(k - stack.size() + 1)大小。
         1.1 如果前者小于或等于后者,则说明不能再出栈了,否则剩余数组全加进栈也不够将栈填到k+1长度。(需要k+1而不是k是因为一开始就填进了-1,但这个-1是不会被返回的)
         1.2 如果前者大于后者,就将队尾元素出栈,并重复第一步

    2、如果栈长度不够,不用判断,直接将当前元素进栈即可。

    class Solution {
         public int[] mostCompetitive(int[] nums, int k) {
     
            Stack<Integer> stack = new Stack<>();
            stack.add(-1);
            int len = nums.length;
     
            for (int i = 0; i < len; i++) {
                //当前元素比队尾元素小,将队尾元素出栈
                //此处需要另外判断数组剩余长度够不够填满栈,不然最后答案长度可能会小于k
                while (nums[i] < stack.peek() && k - stack.size() + 1 < len - i) {
                    stack.pop();
                }
                if (stack.size() < k + 1) {
                    stack.add(nums[i]);
                }
            }
     
            int[] ret = new int[k];
     
            while (k > 0) {
                ret[--k] = stack.pop();
            }
     
            return ret;
        }
    }
     
    //作者链接:https://leetcode-cn.com/problems/find-the-most-competitive-subsequence/solution/java-dan-diao-zhan-by-thedesalizes/

    另外一个图文讲解,辅助理解:传送门

    六、总结

    今天一番解题经历下来,很明显遇到了最后这道题目就卡住了,说明还不够熟悉这方面的知识,存在许多盲区。程序语言是一个方面,关键在于数据结构和算法设计上,思路还不够清晰。所以就此发现了知识的缺漏,之后需要多练习,这么好的平台要利用好๑乛◡乛๑,向大佬们学习提高一下编程能力。

  • 相关阅读:
    U盘安装Ubuntu 14.04 LTS
    VS2013配置OPENCV2.4.9(OPENCV3.X)
    make、makefile、cmake、qmake对比
    Google C++ Style
    Ubuntu16.04搜狗输入法无法输入中文
    Ubuntu16.04安装使用wineqq
    Ubuntu卸载软件
    [机器学习入门篇]-梯度下降法
    [机器学习入门篇]-正则化
    2014年度最受好评的十佳工具
  • 原文地址:https://www.cnblogs.com/chenzhenhong/p/14072684.html
Copyright © 2011-2022 走看看