LeetCode演算法題-Longest Harmonious Subsequence(Java實現)
這是悅樂書的第270 次更新,第284 篇原創
01 看題和準備
今天介紹的是LeetCode演算法題中Easy級別的第136題(順位題號是594)。我們定義一個和諧陣列是一個數組,其最大值和最小值之間的差值恰好為1。給定一個整數陣列,在其所有可能的子序列中找到其最長的和諧子序列的長度。例如:
輸入:[1,3,2,2,5,2,3,7]
輸出:5
說明:最長的和諧子序列是[3,2,2,2,3]。
注意:輸入陣列的長度不會超過20,000。
本次解題使用的開發工具是eclipse,jdk使用的版本是1.8,環境是win7 64位系統,使用Java語言編寫和測試。
02 第一種解法
直接使用兩層for迴圈,依次遍歷元素,如果當前元素在陣列中不存在與之值相差為1的數,標誌flag就為false,那麼此元素就不參與計算,反之存在,就把自己出現的次數與其值相差為1的元素的出現次數加起來,並且flag改為true,取最大值即可。
public int findLHS(int[] nums) { if (nums == null || nums.length < 2) { return 0; } int result = 0; for(int i=0; i<nums.length; i++){ boolean flag = false; int count = 0; for (int j=0; j<nums.length; j++) { if (nums[i] == nums[j]) { count++; } else if (nums[i] == nums[j]-1) { flag = true; count++; } } if (flag) { result = Math.max(result, count); } } return result; }
03 第二種解法
先對陣列進行升序排序,藉助Arrays.sort方法來實現,然後遍歷陣列的元素。
排完序後,可以先將兩種特殊情況直接返回結果,如果排序後的陣列第一個元素與最後一個元素值相等,直接返回0;如果陣列第一個元素與最後一個元素值相差1,返回陣列長度。
如果當前元素連續出現,我們需要先將其出現次數記錄下來,使用變數preCount來存值,在遇到與其值相差為1的元素時,再將與其值相差為1的元素的出現次數記錄下來,加上preCount的值,就表示此和諧陣列的長度,再去與所有可能的和諧陣列長度做比較取最大值。
如果當前元素不是連續出現,那麼preCount的值就為1,表示當前元素只出現了一次,然後判斷下一個元素是否與其值相差1,如果下一個元素符合條件,就找到該元素出現的次數,加上preCount的值,兩次數之和與最大值取較大者。
public int findLHS2(int[] nums) { if (nums == null || nums.length < 2) { return 0; } Arrays.sort(nums); if (nums[0] == nums[nums.length-1]) { return 0; } if (nums[0] == nums[nums.length-1]-1) { return nums.length; } int preCount = 1, result = 0; for (int i = 0; i < nums.length; i++) { int count = 1; if (i > 0 && nums[i] - nums[i - 1] == 1) { while (i < nums.length - 1 && nums[i] == nums[i + 1]) { count++; i++; } result = Math.max(result, count + preCount); preCount = count; } else { while (i < nums.length - 1 && nums[i] == nums[i + 1]) { count++; i++; } preCount = count; } } return result; }
04 第三種解法
使用HashMap,以陣列中的每個元素為key,其出現次數為value,然後遍歷map中的每個key,如果map中含有比當前key值大1的key,那麼將當前key所對應的value與當前key加1後所對應的value相加,就表示一組和諧陣列,在所有可能的和諧陣列中找出最大值即可。為了避免溢位,HashMap中的key的型別取Long。
public int findLHS3(int[] nums) { if (nums == null || nums.length < 2) { return 0; } int result = 0; Map<Long, Integer> map = new HashMap<Long, Integer>(); for (long n : nums) { map.put(n, map.getOrDefault(n, 0)+1); } for (long key : map.keySet()) { if (map.containsKey(key+1)) { result = Math.max(result, map.get(key)+map.get(key+1)); } } return result; }
05 第四種解法
我們可以將上面的解法再精簡下,變成一個迴圈。有一點需要注意,與當前元素能夠組成和諧陣列的數,可能比自己大1,也可能比自己小1,並且可能還在當前元素的後面出現,所以需要將兩種情況都考慮進去。
public int findLHS4(int[] nums) { if (nums == null || nums.length < 2) { return 0; } HashMap<Long, Integer> map = new HashMap<Long, Integer>(); int result = 0; for (long n: nums) { map.put(n, map.getOrDefault(n, 0)+1); if (map.containsKey(n+1)) { result = Math.max(result, map.get(n) + map.get(n+1)); } if (map.containsKey(n-1)) { result = Math.max(result, map.get(n) + map.get(n-1)); } } return result; }
06 小結
演算法專題目前已日更超過四個月 ,演算法題文章137 +篇,公眾號對話方塊回覆【資料結構與演算法 】、【演算法 】、【資料結構 】中的任一關鍵詞,獲取系列文章合集。
以上就是全部內容,如果大家有什麼好的解法思路、建議或者其他問題,可以下方留言交流,點贊、留言、轉發就是對我最大的回報和支援!