11package com .fishercoder .solutions ;
22
3+ import java .util .ArrayList ;
4+ import java .util .List ;
5+
36public class _1570 {
47 public static class Solution1 {
5- /**This is a brute force but accepted solution.
6- * More optimal solution:
7- * use a map to store only non-zero values and use the smaller vector to do multiplication to reduce space and save time.* /
8+ /**
9+ * This is a brute force but accepted solution.
10+ */
811 class SparseVector {
912 int [] vector ;
1013
@@ -23,4 +26,66 @@ public int dotProduct(SparseVector vec) {
2326 }
2427 }
2528 }
29+
30+ public static class Solution2 {
31+ /**
32+ * More optimal solution:
33+ * 1. use a map to store only non-zero values to save space;
34+ * 2. loop through the smaller list;
35+ * 3. use binary search to find the corresponding index in the bigger list if it exists;
36+ */
37+ class SparseVector {
38+ private List <int []> indexAndNumList ;
39+
40+ SparseVector (int [] nums ) {
41+ this .indexAndNumList = new ArrayList <>();
42+ for (int i = 0 ; i < nums .length ; i ++) {
43+ if (nums [i ] != 0 ) {
44+ this .indexAndNumList .add (new int []{i , nums [i ]});
45+ }
46+ }
47+ }
48+
49+ // Return the dotProduct of two sparse vectors
50+ public int dotProduct (SparseVector vec ) {
51+ List <int []> incoming = vec .indexAndNumList ;
52+ if (incoming .size () < this .indexAndNumList .size ()) {
53+ return dotProduct (incoming , this .indexAndNumList );
54+ } else {
55+ return dotProduct (this .indexAndNumList , incoming );
56+ }
57+ }
58+
59+ private int dotProduct (List <int []> smaller , List <int []> bigger ) {
60+ int product = 0 ;
61+ for (int [] indexAndNum : smaller ) {
62+ int [] exists = binarySearch (bigger , indexAndNum [0 ]);
63+ if (indexAndNum [0 ] == exists [0 ]) {
64+ product += indexAndNum [1 ] * exists [1 ];
65+ }
66+ }
67+ return product ;
68+ }
69+
70+ private int [] binarySearch (List <int []> indexAndNumList , int target ) {
71+ int left = 0 ;
72+ int right = indexAndNumList .size () - 1 ;
73+ int [] result = new int []{-1 , 0 };
74+ if (indexAndNumList .get (right )[0 ] < target || indexAndNumList .get (left )[0 ] > target ) {
75+ return result ;
76+ }
77+ while (left <= right ) {
78+ int mid = left + (right - left ) / 2 ;
79+ if (indexAndNumList .get (mid )[0 ] == target ) {
80+ return indexAndNumList .get (mid );
81+ } else if (indexAndNumList .get (mid )[0 ] > target ) {
82+ right = mid - 1 ;
83+ } else {
84+ left = mid + 1 ;
85+ }
86+ }
87+ return new int []{-1 , 0 };
88+ }
89+ }
90+ }
2691}
0 commit comments