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è)元素,然后通過(guò)hashset或者自定義類(lèi),來(lái)去重,這樣肯定超時(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)來(lái)優(yōu)化
- 3.如何優(yōu)化?我們想到這個(gè)是一個(gè)整數(shù)數(shù)組,如果我把它排序之后,其實(shí)第二層遍歷和第三層遍歷,完全可以使用雙指針?lè)桨竵?lái)優(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--,一直往前找,依然無(wú)法找到,則無(wú)法找到
- 6.如果有滿足的元素,則這時(shí)為結(jié)果元素 7.還剩余一個(gè)問(wèn)題,如何去重?題目中要求我們不能有重復(fù)元素,也是利用數(shù)組已排序的點(diǎn),如果數(shù)組排序之后,遍歷過(guò)程中發(fā)現(xiàn)和前一個(gè)元素相同,則實(shí)際上就是重復(fù)了
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
class Solution {
/**
* 解題思路
* 暴力解法:如果直接采用三層for循環(huán),然后去遍歷,找到三個(gè)元素,然后通過(guò)hashset或者自定義類(lèi),來(lái)去重,這樣肯定超時(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)來(lái)優(yōu)化
* 3.如何優(yōu)化?我們想到這個(gè)是一個(gè)整數(shù)數(shù)組,如果我把它排序之后,其實(shí)第二層遍歷和第三層遍歷,完全可以使用雙指針?lè)桨竵?lái)優(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--,一直往前找,依然無(wú)法找到,則無(wú)法找到
* 6.如果有滿足的元素,則這時(shí)為結(jié)果元素
* 7.還剩余一個(gè)問(wèn)題,如何去重?題目中要求我們不能有重復(fù)元素,也是利用數(shù)組已排序的點(diǎn),如果數(shù)組排序之后,遍歷過(guò)程中發(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)文章
Java下利用Jackson進(jìn)行JSON解析和序列化示例
本篇文章主要介紹了Java下利用Jackson進(jìn)行JSON解析和序列化示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-02-02
利用數(shù)組實(shí)現(xiàn)棧(Java實(shí)現(xiàn))
這篇文章主要為大家詳細(xì)介紹了利用數(shù)組實(shí)現(xiàn)棧,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09
在MyBatis中實(shí)現(xiàn)一對(duì)多查詢和多對(duì)一查詢的方式詳解(各兩種方式)
今天通過(guò)兩種方法分別給大家介紹在MyBatis中實(shí)現(xiàn)一對(duì)多查詢和多對(duì)一查詢的方式,每種方式通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧2022-01-01
java中Hutool工具類(lèi)的常見(jiàn)使用場(chǎng)景詳解
在日常開(kāi)發(fā)中,我們會(huì)使用很多工具類(lèi)來(lái)提升項(xiàng)目開(kāi)發(fā)的速度,而國(guó)內(nèi)用的比較多的 Hutool 框架,就是其中之一,本文我們就來(lái)介紹一下Hutool的具體使用吧2023-12-12
Spring5新特性之Reactive響應(yīng)式編程
這篇文章主要介紹了Spring5新特性之Reactive響應(yīng)式編程,響應(yīng)式編程是一種編程范式,通用和專(zhuān)注于數(shù)據(jù)流和變化的,并且是異步的,下文更多詳細(xì)內(nèi)容,需要的小伙伴可以參考一下,希望對(duì)你有所幫助2022-03-03
Java基本類(lèi)型和包裝類(lèi)型的區(qū)別
這篇文章主要介紹了Java基本類(lèi)型和包裝類(lèi)型的區(qū)別,幫助大家更好的理解和學(xué)習(xí)Java,感興趣的朋友可以了解下2020-09-09
Java中如何模擬HTTP請(qǐng)求并驗(yàn)證功能
要模擬HTTP請(qǐng)求并驗(yàn)證功能,你可以使用Spring Boot提供的MockMvc工具,它允許我們?cè)跊](méi)有實(shí)際啟動(dòng)HTTP服務(wù)器的情況下測(cè)試Spring MVC控制器,下面給大家分享如何模擬HTTP請(qǐng)求并驗(yàn)證功能,感興趣的朋友一起看看吧2024-05-05

