C++/Java小白解Leetcode題,發現了知識盲區……

個人博客園:http://www.javashuo.com/article/p-bwwhyjhf-nw.html

個人CSDN博客:https://blog.csdn.net/Charzous/article/details/110355827


 

版權聲明:本文爲博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接和本聲明。
本文連接: https://blog.csdn.net/Charzous/article/details/110355827

1、初見LeetCode

大一時候學習C++,根據課程一直在PTA平臺作題目,數據結構和算法的做業題目也是在PTA。後來發現牛客網學習資源也很豐富,孤陋寡聞,前幾個月在知道LeetCode這個平臺,跟牛客網能夠並稱「程序員的左膀右臂」๑乛◡乛๑。雖然認識了LeetCode,可是一直擠出時間過來練練題,仰慕一下各位大佬的AC。今天就試了幾道題,發現風格與PTA有很大不一樣,還須要不斷去熟悉,別具風格的打題也挺有意思,經過幾個簡單題目,發現本身知識盲區,但願可以學習到更多!下面記錄一下幾個題目的思路解法。html

2、字符串中的單詞數

題目:java

統計字符串中的單詞個數,這裏的單詞指的是連續的不是空格的字符。程序員

請注意,你能夠假定字符串裏不包括任何不可打印的字符。算法

示例:編程

  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)
著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
*/

3、最富有客戶的資產總量

給你一個 m x n 的整數網格 accounts ,其中 accounts[i][j] 是第 i​​​​​ 位客戶在第 j 家銀行託管的資產數量。返回最富有客戶所擁有的 資產總量 。ide

客戶的 資產總量 就是他們在各家銀行託管的資產數量之和。最富有客戶就是 資產總量 最大的客戶。

 

示例 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;
    
    }
}

4、三角形的最大周長

給定由一些正數(表明長度)組成的數組 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;
    }
}

5、找出最具競爭力的子序列(中等難度)

給你一個整數數組 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
著做權歸領釦網絡全部。商業轉載請聯繫官方受權,非商業轉載請註明出處。

前面幾道屬於簡單類型,這道中等題目就顯得有些份量了,題目須要琢磨一會才知道是要幹啥,就題作題。

看到一個大佬的解題思路,這個比較好理解:傳送門

維護一個單調棧,從左到右遍歷數組。

一、若是當前元素比隊尾元素小,接下來判斷剩餘數組長度(len - i)和目標棧還須要元素個數(k - stack.size() + 1)大小。
     1.1 若是前者小於或等於後者,則說明不能再出棧了,不然剩餘數組全加進棧也不夠將棧填到k+1長度。(須要k+1而不是k是由於一開始就填進了-1,但這個-1是不會被返回的)
     1.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/

另一個圖文講解,輔助理解:傳送門

6、總結

今天一番解題經歷下來,很明顯遇到了最後這道題目就卡住了,說明還不夠熟悉這方面的知識,存在許多盲區。程序語言是一個方面,關鍵在於數據結構和算法設計上,思路還不夠清晰。因此就此發現了知識的缺漏,以後須要多練習,這麼好的平臺要利用好๑乛◡乛๑,向大佬們學習提升一下編程能力。

相關文章
相關標籤/搜索