我的部落格園:https://www.cnblogs.com/chenzhenhong/p/14072684.html
我的CSDN部落格:https://blog.csdn.net/Charzous/article/details/110355827
一、初見LeetCode
大一時候學習C++,根據課程一直在PTA平臺做題目,資料結構和演算法的作業題目也是在PTA。後來發現牛客網學習資源也很豐富,孤陋寡聞,前幾個月在知道LeetCode這個平臺,跟牛客網可以並稱“程式設計師的左膀右臂”๑乛◡乛๑。雖然認識了LeetCode,但是一直擠出時間過來練練題,仰慕一下各位大佬的AC。今天就試了幾道題,發現風格與PTA有很大不同,還需要不斷去熟悉,別具風格的打題也挺有意思,通過幾個簡單題目,發現自己知識盲區,希望能夠學習到更多!下面記錄一下幾個題目的思路解法。
二、字串中的單詞數
題目:
統計字串中的單詞個數,這裡的單詞指的是連續的不是空格的字元。
請注意,你可以假定字串裡不包括任何不可列印的字元。
示例:
輸入: "Hello, my name is John" 輸出: 5 解釋: 這裡的單詞是指連續的不是空格的字元,所以 "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++手寫方法,效果更好:
思路:使用一個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/
另外一個圖文講解,輔助理解:傳送門
六、總結
今天一番解題經歷下來,很明顯遇到了最後這道題目就卡住了,說明還不夠熟悉這方面的知識,存在許多盲區。程式語言是一個方面,關鍵在於資料結構和演算法設計上,思路還不夠清晰。所以就此發現了知識的缺漏,之後需要多練習,這麼好的平臺要利用好๑乛◡乛๑,向大佬們學習,提高一下程式設計能力。