[英]Two Sum LeetCode Java Questions
我正在嘗試在 LeetCode 上進行 Java 模擬面試。 我有以下問題:
給定一個整數數組,返回兩個數字的索引,使它們相加到一個特定的目標。
您可能會假設每個輸入都只有一個解決方案,並且您可能不會兩次使用相同的元素。
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
我試圖實現一個遞歸解決方案。 但是,我在嘗試運行我的代碼時收到錯誤消息。
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] sumnums = nums.clone();
//int[2] sol = {0,1};
int[] sol = new int[]{0,1};
sol = new int[2];
int j=sumnums.length;
int t=target;
for(int i=0;i<sumnums.length;i++){
if ((sumnums[i]+sumnums[j])==t){
sol[0]=i;
sol[1]=j;
//return sol;
}
}
j=j-1;
twoSum(sumnums,t);
return sol;
}
}
錯誤:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
at Solution.twoSum(Solution.java:12)
at __DriverSolution__.__helper__(__Driver__.java:8)
at __Driver__.main(__Driver__.java:54)
在我看來,錯誤可能與以下代碼行有關:
if ((sumnums[i]+sumnums[j])==t){
因此,我想知道這是否是與語法相關的錯誤。 我正在嘗試檢查兩個數字加起來是否為不同的數字。
由於這是對遞歸解決方案的幼稚嘗試,因此我很樂意接受任何其他批評。 但我最關心的是讓我在這個問題上的嘗試與所有測試用例一起工作和運行。
謝謝。
方法 1. 簡單的方法:使用兩個 for 循環簡單的方法是只使用兩個嵌套的 for 循環並檢查數組中任意兩個元素的總和是否等於給定的目標。
時間復雜度:O(n^2)
// Time complexity: O(n^2)
private static int[] findTwoSum_BruteForce(int[] nums, int target) {
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] == target) {
return new int[] { i, j };
}
}
}
return new int[] {};
}
方法 2. 使用 HashMap(最有效)您可以使用 HashMap 來解決 O(n) 時間復雜度的問題。 以下是步驟:
初始化一個空的HashMap。 遍歷數組的元素。 對於數組中的每個元素 - 如果該元素存在於 Map 中,則檢查它是否是補碼(目標 - 元素)也存在於 Map 中。 如果存在補碼,則返回當前元素的索引和補碼。 否則,將元素放入 Map 中,然后進行下一次迭代。 時間復雜度:O(n)
// Time complexity: O(n)
private static int[] findTwoSum(int[] nums, int target) {
Map<Integer, Integer> numMap = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int complement = target - nums[i];
if (numMap.containsKey(complement)) {
return new int[] { numMap.get(complement), i };
} else {
numMap.put(nums[i], i);
}
}
return new int[] {};
}
方法 3. 使用排序和兩指針滑動窗口方法當您需要返回數字而不是它們的索引時,還有另一種方法可以使用。 下面是它的工作原理:
對數組進行排序。 初始化兩個變量,一個指向數組的開頭(左),另一個指向數組的結尾(右)。 循環直到左 < 右,並且對於每次迭代
如果 arr[left] + arr[right] == target,則返回索引。 如果 arr[left] + arr[right] < target,增加左索引。
否則,減少正確的索引。 這種方法稱為兩指針滑動窗口方法。 這是解決數組相關問題的一種非常常見的模式。
時間復雜度:O(n*log(n))
// Time complexity: O(n*log(n))
private static int[] findTwoSum_Sorting(int[] nums, int target) {
Arrays.sort(nums);
int left = 0;
int right = nums.length - 1;
while(left < right) {
if(nums[left] + nums[right] == target) {
return new int[] {nums[left], nums[right]};
} else if (nums[left] + nums[right] < target) {
left++;
} else {
right--;
}
}
return new int[] {};
}
為什么不使用 HashMap? 這是它的工作原理。 我們將遍歷數組並檢查target - nums[i]
是否存在於地圖中。 如果不是,我們將Key, Value
分別存儲為數字及其索引,即K = nums[i], V = i
以下是它的工作原理:考慮nums = [2, 7, 11, 15], target = 9
我們將開始迭代數組
首先是 2。這里我們將檢查 (9 - 2) 即 7 在 hashmap 中不存在,因此我們將存儲 2 作為鍵,並將其索引 0 作為其值
然后是 7。這里我們將檢查 (9 - 7) 即 2 存在於地圖中,因此我們將返回 2 的索引和 7 的索引,即返回 [ 0, 1 ]
public int[] twoSum(int[] nums, int target) {
HashMap<Integer,Integer> map = new HashMap<>();
for(int i = 0; i < nums.length; i++)
{
if(map.containsKey(target - nums[i]))
{
return new int[] {map.get(target-nums[i]),i};
}
else
map.put(nums[i],i);
}
return new int[] {-1,-1};
}
正如您提到的,首先是 2。在這里我們將檢查 (9 - 2) 即 7 在哈希圖中不存在
實際上7確實存在於 HashMap right nums = [2, 7, 11, 15], target = 9
public static int[] twoSum(int[] nums, int target) {
int[] sumnums = nums.clone();
//int[2] sol = {0,1};
int[] sol = new int[]{0,1};
sol = new int[2];
int j=sumnums.length; // Every recursion j will be initialized as sumnums.length instead of J-1
int t=target;
for(int i=0;i<sumnums.length;i++){
// if ((sumnums[i]+sumnums[j])==t){
// Remember that Java arrays start at index 0, so this value(sumnums[j]) is not exist in the array.
if ((sumnums[i]+sumnums[j-1])==t){
sol[0]=i;
sol[1]=j;
return sol;
}
}
j=j-1;
twoSum(sumnums,t);
return sol;
}
許多可能的解決方案之一:
public class TwoSumIndex {
public static void main(String... args) {
int[] arr = {2, 7, 11, 15, 9, 0, 2, 7};
System.out.println(findTwoSums(arr, 9));
}
private static List<List<Integer>> findTwoSums(int[] arr, int target) {
Set<Integer> theSet = Arrays.stream(arr).mapToObj(Integer::valueOf).collect(Collectors.toSet());
List<Integer> arrList = Arrays.stream(arr).mapToObj(Integer::valueOf).collect(Collectors.toList());
List<Pair<Integer, Integer>> theList = new ArrayList<>();
List<Integer> added = new ArrayList<>();
for (int i = 0; i < arr.length; i++) {
int a = target - arr[i];
if (theSet.contains(a) && added.indexOf(i) < 0) { // avoid duplicates;
Integer theOther = arrList.indexOf(a);
theList.add(new Pair(i, theOther));
added.add(i);
added.add(theOther);
}
}
return theList.stream().map(pair -> new ArrayList<>(Arrays.asList(pair.getKey(), pair.getValue())))
.collect(Collectors.toList());
}
}
您需要了解幾件事:
O(N^2)
但實際上會低很多,因為theSet.contains(a)
O(logN) 會過濾掉所有失敗的索引,然后做索引重復O(N) 檢查,所以實際的時間復雜度應該是O(NlogN)
;演示的輸出:
[[0, 1], [4, 5], [6, 1], [7, 0]]
我使用更簡單的方法
類解決方案 { public int[] twoSum(int[] nums, int target) {
int[] indices= new int[2];
int len=nums.length;
for(int i=0; i<len; i++){
for(int j=i+1; j<len;j++){
if((nums[i]+nums[j])==target){
indices[0] = i;
indices[1] = j;
return indices;
}
}
}
return null;
}
}
Complete code for beginners
//Predefined values
import java.util.Arrays;
public class TwoSum {
public static void main(String args[]) {
Solution solution = new Solution();
int target = 9;
int num[] = {2, 7, 11, 15};
num = solution.twoSum(num, target);
System.out.println(Arrays.toString(num));
}
}
class Solution {
public int[] twoSum(int[] nums, int target) {
int result[] = new int[2];
int sum;
for (int i = 0; i + 1 < nums.length; i++) {
// adding the alternate numbers
sum = nums[i] + nums[i + 1];
if (sum == target) {
result[0] = i;
result[1] = i + 1;
return result;
}
}
return null;
}
}
************************************************************************
//User-defined
import java.util.Arrays;
import java.util.Scanner;
/**
*
* @author shelc
*/
public class TwoSum {
public static void main(String[] args) {
Solution solution = new Solution();
Scanner scanner = new Scanner(System.in);
int n;
System.out.print("Enter the number of elements : ");
n = scanner.nextInt();
int array[] = new int[10];
System.out.println("Enter the array elemets : ");
for (int i = 0; i < n; i++) {
array[i] = scanner.nextInt();
}
int target;
System.out.println("Enter the target : ");
target = scanner.nextInt();
int nums[] = solution.twoSum(array, target);
System.out.println(Arrays.toString(nums));
}
}
class Solution {
public int[] twoSum(int nums[], int target) {
int result[] = new int[2];
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
if ((nums[i] + nums[j]) == target) {
result[0] = i;
result[1] = j;
return result;
}
}
}
return null;
}
}
public static int[] twoSum(int[] nums, int target) {
int[] arr = new int[2];
int arrIndex =0;
for(int i =0; i<nums.length; i++){
for(int j = 0;j<nums.length-1;j++){
if( i!=j) {// don't check to itself
if (nums[i] + nums[j] == target) {
arr[arrIndex] = i;
arr[arrIndex + 1] = j;
break;
}
}
}
}
Arrays.sort(arr);
return arr;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.