Reduce ZippedPartitionsRDD's getPreferredLocations complexity from O(2^2n) to O(2^n)

ZippedPartitionsRDD's `getPreferredLocations()` complexity is now O(2^2n), which will become a efficiency problem when running iterative job or streaming job that uses previous calculated RDD, for example:

```
  var zipRdd = ...
  for (i  <-  1 to 100)
    val newRdd = ...
    zipRdd = zipRdd.zipPartitions(f, newRdd)
  }
```

This patch reduce complexity from O(2^2n) to originally O(2^n) while keep algorithm the same as before.