java算法題解Leetcode15三數(shù)之和實(shí)例
題目
給你一個(gè)包含 n 個(gè)整數(shù)的數(shù)組 nums,判斷 nums 中是否存在三個(gè)元素 a,b,c ,使得 a + b + c = 0 ?請(qǐng)你找出所有和為 0 且不重復(fù)的三元組。 注意:答案中不可以包含重復(fù)的三元組。
示例 1:
輸入:nums = [-1,0,1,2,-1,-4]
輸出:[[-1,-1,2],[-1,0,1]]
示例 2:
輸入:nums = []
輸出:[]
示例 3:
輸入:nums = [0]
輸出:[]
提示:
0 <= nums.length <= 3000
-105 <= nums[i] <= 105
解題思路
暴力解法:如果直接采用三層for循環(huán),然后去遍歷,找到三個(gè)元素,然后通過hashset或者自定義類,來去重,這樣肯定超時(shí)
- 1.我們需要去想一下,如何優(yōu)化算法,條件是a+b+c=0,其實(shí)我們可以優(yōu)化為找到a+b=-c
- 2.三層for循環(huán)是根本,第一層和第二層循環(huán)不可避免,第三層需要可以利用a+b==-c的點(diǎn)來優(yōu)化
- 3.如何優(yōu)化?我們想到這個(gè)是一個(gè)整數(shù)數(shù)組,如果我把它排序之后,其實(shí)第二層遍歷和第三層遍歷,完全可以使用雙指針方案來優(yōu)化
- 4.第三層for循環(huán),可以優(yōu)化為一個(gè)k指針(默認(rèn)位置為int k = nums.length - 1),有一個(gè)k指針從后往前,找尋nums[j] + nums[k] == nums[i]的元素
- 5.如果k--,一直往前找,依然無法找到,則無法找到
- 6.如果有滿足的元素,則這時(shí)為結(jié)果元素 7.還剩余一個(gè)問題,如何去重?題目中要求我們不能有重復(fù)元素,也是利用數(shù)組已排序的點(diǎn),如果數(shù)組排序之后,遍歷過程中發(fā)現(xiàn)和前一個(gè)元素相同,則實(shí)際上就是重復(fù)了
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
class Solution {
/**
* 解題思路
* 暴力解法:如果直接采用三層for循環(huán),然后去遍歷,找到三個(gè)元素,然后通過hashset或者自定義類,來去重,這樣肯定超時(shí)
* 1.我們需要去想一下,如何優(yōu)化算法,條件是a+b+c==0,其實(shí)我們可以優(yōu)化為找到a+b==-c
* 2.三層for循環(huán)是根本,第一層和第二層循環(huán)不可避免,第三層需要可以利用a+b==-c的點(diǎn)來優(yōu)化
* 3.如何優(yōu)化?我們想到這個(gè)是一個(gè)整數(shù)數(shù)組,如果我把它排序之后,其實(shí)第二層遍歷和第三層遍歷,完全可以使用雙指針方案來優(yōu)化
* 4.第三層for循環(huán),可以優(yōu)化為一個(gè)k指針(默認(rèn)位置為int k = nums.length - 1),有一個(gè)k指針從后往前,找尋nums[j] + nums[k] == nums[i]的元素
* 5.如果k--,一直往前找,依然無法找到,則無法找到
* 6.如果有滿足的元素,則這時(shí)為結(jié)果元素
* 7.還剩余一個(gè)問題,如何去重?題目中要求我們不能有重復(fù)元素,也是利用數(shù)組已排序的點(diǎn),如果數(shù)組排序之后,遍歷過程中發(fā)現(xiàn)和前一個(gè)元素相同,則實(shí)際上就是重復(fù)了
* @param nums
* @return
*/
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> target = new ArrayList<List<Integer>>();
if (nums == null || nums.length < 2) {
return target;
}
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
// 需要和上一次枚舉的數(shù)不相同
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
for (int j = i + 1; j < nums.length; j++) {
// 需要和上一次枚舉的數(shù)不相同
if (j > i + 1 && nums[j] == nums[j - 1]) {
continue;
}
int temp = -nums[i];
int k = nums.length - 1;
while (nums[j] + nums[k] > temp && j < k) {
k--;
}
// 如果指針重合,隨著 b 后續(xù)的增加
// 就不會(huì)有滿足 a+b+c=0 并且 b<c 的 c 了,可以退出循環(huán)
if (j == k) {
break;
}
if (nums[i] + nums[j] + nums[k] == 0) {
List<Integer> list = new ArrayList<Integer>();
list.add(nums[i]);
list.add(nums[j]);
list.add(nums[k]);
target.add(list);
}
}
}
return target;
}
}以上就是java算法題解Leetcode15三數(shù)之和實(shí)例的詳細(xì)內(nèi)容,更多關(guān)于java算法三數(shù)之和的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot實(shí)現(xiàn)過濾器Filter的三種方式
過濾器Filter由Servlet提供,基于函數(shù)回調(diào)實(shí)現(xiàn)鏈?zhǔn)綄?duì)網(wǎng)絡(luò)請(qǐng)求與響應(yīng)的攔截與修改,本文講給大家詳細(xì)介紹SpringBoot實(shí)現(xiàn)過濾器Filter的三種方式,需要的朋友可以參考下2023-08-08
Java?集合框架掌握?Map?和?Set?的使用(內(nèi)含哈希表源碼解讀及面試??碱})
這篇文章主要介紹了Java?集合框架掌握?Map?和?Set?的使用并含有內(nèi)含哈希表源碼解讀及面試??碱},?Map?和?Set?是一種適合動(dòng)態(tài)查找的集合容器或者數(shù)據(jù)結(jié)構(gòu)下面文章詳細(xì)介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2021-12-12
使用maven-assembly-plugin如何打包多模塊項(xiàng)目
這篇文章主要介紹了使用maven-assembly-plugin如何打包多模塊項(xiàng)目,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
Spring整合mybatis實(shí)現(xiàn)過程詳解
這篇文章主要介紹了Spring整合mybatis實(shí)現(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07
Jmeter自定義函數(shù)base64加密實(shí)現(xiàn)過程解析
這篇文章主要介紹了Jmeter自定義函數(shù)base64加密實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07
Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(36)
下面小編就為大家?guī)硪黄狫ava基礎(chǔ)的幾道練習(xí)題(分享)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧,希望可以幫到你2021-07-07
SpringBoot通過@Value實(shí)現(xiàn)給靜態(tài)變量注入值詳解
這篇文章主要介紹了springboot如何通過@Value給靜態(tài)變量注入值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07
Java模擬新浪和騰訊自動(dòng)登錄并發(fā)送微博
這篇文章主要為大家詳細(xì)介紹了Java模擬新浪和騰訊自動(dòng)登錄并發(fā)送微博功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-07-07

