Given an array of integers and an integer k, find out whether there are two distinct indices i and j in the array such that nums[i] = nums[j] and the absolute difference between i and j is at most k.
Example 1:
Input: nums = [1,2,3,1], k = 3
Output: true
Example 2:
Input: nums = [1,0,1,1], k = 1
Output: true
object Solution {
def containsNearbyDuplicate(nums: Array[Int], k: Int): Boolean = {
for (i <- 0 until nums.length - 2) {
for (j <- i until nums.length - 1) {
if (nums(i) == nums(j) && (j - i == k)) return true
}
}
return false
}
}
Your input
[1,2,3,1]
3
Output
false
Expected
true
I don't think you're evaluating the full length of the inner list.
As written, j will never equal 3.
I think if you make your inner loop read for (j <- i until nums.length) that should work.
Probably want to fix the outer loop too. Otherwise, i will never reach the value of 3 stored in your array.
Using until will exclude, so if you use i <- 0 until nums.length -1 where length is 3, then the value of i will be 0, 1, 2 and end.
If you want to subtract - 1 because it feels easier or makes more sense to you, then you probably want to use i <- 0 to nums.length - 1.
Otherwise, i <-0 until nums.length will result in the value of i being 0, 1, 2, 3 as it iterates through the for loop.
Hope that helps.
This is functional, efficient as O(n) instead of O(n^2) and fixes a bug(i != j). You should always have a negative case too when testing ;)
import math.{min, max}
def containsNearbyDuplicate(nums: Array[Int])(k: Int): Boolean = {
val indexesToCheck = for {
i <- 0 until nums.length
j <- max(0, i - k) to min(nums.length - 1, i + k)
if i != j
} yield (i, j)
indexesToCheck.exists {case (i, j) => nums(i) == nums(j)}
}
containsNearbyDuplicate(nums = Array(1, 2, 3, 1, 5))(k = 3)
containsNearbyDuplicate(nums = Array(1, 2, 3, 1, 5))(k = 2)
containsNearbyDuplicate(nums = Array(1, 0, 1, 1, 5))(k = 1)
Related
Imagine the following List[Int] in Scala:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
I want to apply kind of a dynamic filter to it such that towards head/tail less data is filtered compared to the middle of the list:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
_ ____ __________ ___________ ______ __
[0, 1, 3, 7, 11, 13] // result
To do this, from both ends an index is increased by the next power of 2 and from the middle onwards the powers of 2 decrease again:
0, 0 + 2**0 = 1, 1 + 2**1 = 3, 3 + 2^2 = 7, etc.
To achieve this with an imperative approach, code similar to this can be used:
var log = 0
var idx = 0
val mask: ListBuffer[Int] = mutable.ListBuffer()
while (idx < buffer.size) {
mask += idx
if (idx + (2 ** log) < buffer.size / 2) {
idx += 2 ** log
log += 1
} else {
idx = buffer.size - (2 ** log) + 1
log -= 1
}
}
This produces a mask array that can then be used to filter the original list like mask.flatMap(list.lift)
Can somebody help me do this in a more concise, functional way?
What I basically need is a way to filter the list using some changing state from the outside.
Thanks in advance.
The usual approach to iterating with state is tail recursion (or you often do the same thing with reduceLeft with simple enough cases).
This is better than the other answer, because it is linear (accessing list elements by index makes the whole thing quadratic), and tail-recursive (no extra space on stack). Also, I think, the other version reverses the order of filtered elements.
You can do it with recursively in one go (this is better than the other answer, because it is tail-recursive, and linear (accessing list elements by index makes the implementation quadratic).
I didn't check the logic, which the other answer suggested was incorrect, just used it as is from your snippet, but here is the idea:
#tailrec
def filter(
in: List[Int],
midpoint: Int,
out: List[Int]=Nil,
idx: Int = 0,
next: Int = 0,
log: Int = 0
): List[Int] = in match {
case Nil => out.reverse
case head::tail if (idx == next) =>
filter(tail, midpoint, head::out, idx+1, idx + pow(2, log).toInt, if (idx < midpoint) log + 1 else log-1)
case head::tail => filter(tail, midpoint, out, idx+1, next, log)
}
Note, that this may seem less efficient than your "mask" idea because it looks at every element in the list, rather than jumping over indices being filtered out, but in fact, as long as you are working with List, it is actually more efficient: first, yours is (at least) O(N) anyway, because you have to traverse the whole list to figure out the size, and secondly, list.lift(idx) is O(idx), so towards the end of the list, this will be require multiple traversals of almost entire list.
Now, if you had an indexed container instead of a list, the whole "masking" idea would indeed improve things:
def filter(list: IndexedSeq[Int]) = {
val size = list.size
Iterator.iterate((0, 0)) { case (idx, log) =>
(idx + math.pow(2, log).toInt, if idx < size/2 log+1 else log-1)
}.map(_._1).takeWhile(_ < size).map(list)
}
You code snippet does not work very well, I had to tweak it a bit to make it output the result you want:
var log = 0
var idx = 0
val resultList: mutable.ListBuffer[Int] = mutable.ListBuffer()
// Fill the result until the middle, increasing the jump size
while (idx < list.size / 2) {
resultList += list(idx)
idx += math.pow(2, log).toInt
log += 1
}
// Fill the result from the middle until the end, decreasing the jump size again
while (idx < list.size && log >= 0) {
resultList += list(idx)
log -= 1
idx += math.pow(2, log).toInt
}
With your example it works:
val list = (0 to 13).toList -> ListBuffer(0, 1, 3, 7, 11, 13)
However with another example I got that:
val list = (0 to 22).toList -> ListBuffer(0, 1, 3, 7, 15)
I don't think this is really what you want, do you?
Anyway here is a more functionnal version of it:
def filter(list: List[Int]) = {
// recursive function to traverse the list
def recursive(l: List[Int], log: Int, idx: Int, size: Int, halfSize: Int): List[Int] = {
if (idx >= l.size || log < 0) // terminal case: end of the list
Nil
else if (idx < l.size / 2) // first half of the list: increase the jump size
l(idx) :: recursive(l, log + 1, idx + math.pow(2, log).toInt, size, halfSize)
else // second half of the list: decrease the jump size
l(idx) :: recursive(l, log - 1, idx + math.pow(2, log-1).toInt, size, halfSize)
}
// call the recursive function with initial parameters
recursive(list, 0, 0, list.size, list.size / 2)
}
However, jumping by powers if 2 is too aggressive. If you are near the middle of the list, the next jump will ends at the very end, and you will not be able to get a progressive jump decay.
Another solution could be to increase the jump size by one each time instead of working with powers of 2. You can also keep a constant jump size when you are near the middle of the list to avoid skipping too much values in the second half before starting to reduce the jump size:
def filter2(list: List[Int]) = {
def recursive(l: List[Int], jumpsize: Int, idx: Int, size: Int, halfSize: Int): List[Int] = {
if (idx >= l.size) // terminal case: end of the list
Nil
else if (idx + jumpsize < l.size/2) // first half of the list: increase the jump size
l(idx) :: recursive(l, jumpsize+1, idx + jumpsize, size, halfSize)
else if (idx < l.size/2) // around the middle of the list: keep the jump size
l(idx) :: recursive(l, jumpsize, idx + jumpsize, size, halfSize)
else { // second half of the list: decrease the jump size
val nextJumpSize = jumpsize - 1
l(idx) :: recursive(l, nextJumpSize, idx + nextJumpSize, size, halfSize)
}
}
// call the recursive function with initial parameters
recursive(list, 1, 0, list.size, list.size / 2)
}
In my opinion, the results with this version are a bit better:
val list = (0 to 22).toList -> List(0, 1, 3, 6, 10, 15, 19, 22)
Your question is not so clear for some corner case, here is my solution:
scala> def filter[A](seq: Seq[A], n: Int = 1): Seq[A] = seq match {
| case Nil => Nil
| case Seq(x) => Seq(x)
| case _ => seq.head +: filter(seq.drop(n).dropRight(2*n), 2*n) :+ seq.last
| }
def filter[A](seq: Seq[A], n: Int): Seq[A]
scala> filter(0 to 13)
val res0: Seq[Int] = List(0, 1, 3, 7, 11, 13)
scala> filter(0 to 100)
val res1: Seq[Int] = List(0, 1, 3, 7, 15, 31, 38, 70, 86, 94, 98, 100) // I am not sure if 38 should in the result
I would like to know if below function can be rewritten using tail recursion and using recursion in this case is any helpful in terms of time/space complexity?, below is what i have tried without tail recursion
input:[4,2,4,6]
output:[48,96,48,32]
def productExceptSelf(nums: Array[Int]): Array[Int]={
val len = nums.length
val output_arr= new Array[Int](len)
output_arr(0)=1
for(i<- 1 to len-1)
{
output_arr(i) = nums(i-1) * output_arr(i-1)
}
var R =1
var j=len-1
while(j>=0)
{
output_arr(j) = output_arr(j)* R
R = R * nums(j)
j-=1
}
output_arr
}
Solution without using division.
def productExceptSelf(nums: Array[Int]): Array[Int] =
Array.fill(nums.length)(nums)
.zipWithIndex
.map{case (ns,x) => ns.patch(x,Seq(),1).product}
Not sure how would you expect to write this using tail-recursion, but the simplest way would be something like this:
PS: I am using ArraySeq which is an immutable array (that was introduced on 2.13), feel free to keep using normal arrays.
def productExceptSelf(nums: ArraySeq[Int]): ArraySeq[Int] = {
val totalProduct = nums.product
nums.map(x => totalProduct / x)
}
Solution without using division.
def productExceptSelf(nums: ArraySew[Int]) : ArraySeq[Int] =
ArraySeq.tabulate(nums.length) { i =>
nums.foldLeft(1 -> 0) { case ((acc, j), x) =>
val newAcc = if (i == j) acc else acc * x
newAcc -> (j + 1)
}._1
}
Try this. It keeps track of the index and multiplies if the index of the current element isn't the same. However, it's not very idiomatic.
def productExceptSelf(nums: Array[Int]): Array[Int] =
productExceptSelf(nums, Array.fill(nums.size)(1), 0).toArray
def productExceptSelf(orig: Array[Int], res: Array[Int], i: Int): Array[Int] =
if (i == orig.size) res
else productExceptSelf(
orig,
res.zipWithIndex.map {
case (n, j) => if (j == i) n else n * orig(i)
},
i + 1
)
I like this one better:
def productExceptSelf(nums: Array[Int]): Array[Int] =
nums.indices.map {
i => nums.slice(0, i).product * nums.slice(i + 1, nums.size).product
}.toArray
You might prefer a view to do it lazily
def productExceptSelf(nums: Array[Int]) =
nums.indices.map {
i => nums.view.slice(0, i).product * nums.view.slice(i + 1, nums.size).product
}
# Starting from the right and recursing left, compute the right side product
# and pass it down. Upon reaching the left, compute the left side product,
# update the array, and bubble that value up.
def prod_not_self(arr, i, right):
if (i == 0):
left = 1
else:
left = arr[i-1] * prod_not_self(arr, i - 1, right * arr[i])
arr[i] = right * left
return left
if (__name__ == '__main__'):
arr = [1, 2, 3, 4]
print(arr)
prod_not_self(arr, len(arr) - 1, 1)
print(arr)
print()
arr = [-1, 1, 0, -3, 3]
print(arr)
prod_not_self(arr, len(arr) - 1, 1)
print(arr)
I am wondering if there's a way to deal with a while (n > 0) loop in a more functional way, I have a small Scala app that counts the number of digits equal to K from a range from 1 to N:
for example 30 and 3 would return 4 [3, 13, 23, 30]
object NumKCount {
def main(args: Array[String]): Unit = {
println(countK(30,3))
}
def countKDigit(n:Int, k:Int):Int = {
var num = n
var count = 0
while (num > 10) {
val digit = num % 10
if (digit == k) {count += 1}
num = num / 10
}
if (num == k) {count += 1}
count
}
def countK(n:Int, k:Int):Int = {
1.to(n).foldLeft(0)((acc, x) => acc + countKDigit(x, k))
}
}
I'm looking for a way to define the function countKDigit using a purely functional approach
First expand number n into a sequence of digits
def digits(n: Int): Seq[Int] = {
if (n < 10) Seq(n)
else digits(n / 10) :+ n % 10
}
Then reduce the sequence by counting occurrences of k
def countKDigit(n:Int, k:Int):Int = {
digits(n).count(_ == k)
}
Or you can avoid countKDigit entirely by using flatMap
def countK(n:Int, k:Int):Int = {
1.to(n).flatMap(digits).count(_ == k)
}
Assuming that K is always 1 digit, you can convert n to String and use collect or filter, like below (there's not much functional stuff you can do with Integer):
def countKDigit(n: Int, k: Int): Int = {
n.toString.collect({ case c if c.asDigit == k => true }).size
}
or
def countKDigit(n: Int, k: Int): Int = {
n.toString.filter(c => c.asDigit == 3).length
}
E.g.
scala> 343.toString.collect({ case c if c.asDigit == 3 => true }).size
res18: Int = 2
scala> 343.toString.filter(c => c.asDigit == 3).length
res22: Int = 2
What about the following approach:
scala> val myInt = 346763
myInt: Int = 346763
scala> val target = 3
target: Int = 3
scala> val temp = List.tabulate(math.log10(myInt).toInt + 1)(x => math.pow(10, x).toInt)
temp: List[Int] = List(1, 10, 100, 1000, 10000, 100000)
scala> temp.map(x => myInt / x % 10)
res17: List[Int] = List(3, 6, 7, 6, 4, 3)
scala> temp.count(x => myInt / x % 10 == target)
res18: Int = 2
Counting the occurrences of a single digit in a number sequence.
def countK(n:Int, k:Int):Int = {
assert(k >= 0 && k <= 9)
1.to(n).mkString.count(_ == '0' + k)
}
If you really only want to modify countKDigit() to a more functional design, there's always recursion.
def countKDigit(n:Int, k:Int, acc: Int = 0):Int =
if (n == 0) acc
else countKDigit(n/10, k, if (n%10 == k) acc+1 else acc)
I have the following function which I have checked about a dozen times, and should work exactly as I want, but it ends up with the wrong result. Can anyone point out what is wrong with this function?
Note: I'm printing out the list that is being passed in recursive calls; and the list is exactly as I expect it to be. But the variable called result that accumulates the result does not contain the correct permutations at the end. Also, I synchronized the access to result variable, but that did NOT fix the problem; so, I don't think synchronization is a problem. The code can be copied and run as is.
import collection.mutable._
def permute(list:List[Int], result:StringBuilder):Unit =
{
val len = list.size
if (len == 0) (result.append("|"))
else
{
for (i <- 0 until len )
{
println("========" + list + "===========")
result.append( list(i) )
if (i != len -1)
{
//println("Adding comma since i is: " + i)
result.append(", ")
}
//println("******** Reslut is:" + result + "***********")
permute( (sublist(list, i) ), result)
}
}
// This function removes just the ith item, and returns the new list.
def sublist (list:List[Int], i:Int): List[Int] =
{
var sub:ListBuffer[Int] = (list.map(x => x)).to[ListBuffer]
sub.remove(i)
return sub.toList
}
}
var res = new StringBuilder("")
permute(List(1,2,3), res)
println(res)
The output is:
========List(1, 2, 3)===========
========List(2, 3)===========
========List(3)===========
========List(2, 3)===========
========List(2)===========
========List(1, 2, 3)===========
========List(1, 3)===========
========List(3)===========
========List(1, 3)===========
========List(1)===========
========List(1, 2, 3)===========
========List(1, 2)===========
========List(2)===========
========List(1, 2)===========
========List(1)===========
**1, 2, 3|32|2, 1, 3|31|31, 2|21|**
I think Dici's solution is good, but kind of cryptic. I think the following code is much more clear:
def permutations(list: List[Int]): List[List[Int]] = list match
{
case Nil | _::Nil => List(list)
case _ =>(
for (i <- list.indices.toList) yield
{
val (beforeElem, afterElem) = list.splitAt(i)
val element = afterElem.head
val subperm = permutations (beforeElem ++ afterElem.tail)
subperm.map(element:: _)
}
).flatten
}
val result = permutations(List (1,2,3,4,5) )
println(result.mkString("\n") )
The output will be:
List(1, 2, 3)
List(1, 3, 2)
List(2, 1, 3)
List(2, 3, 1)
List(3, 1, 2)
List(3, 2, 1)
There are various problems with your approach, the main one being that you don't actually implement the recurrence relation between the permutations of n elements and the permutations of n + 1 elements, which is that you can take all permutations of n elements and insert the n + 1th element at every position of every permutation of n elements to get all the permutations of n + 1 elements.
One way to do it, more Scalatically, is:
def sortedPermutations(list: List[Int]): List[List[Int]] = list match {
case Nil | _ :: Nil => List(list)
case _ => list.indices.flatMap(i => list.splitAt(i) match {
case (head, t :: tail) => sortedPermutations(head ::: tail).map(t :: _)
}).toList
}
println(sortedPermutations(List(1, 2, 3)).map(_.mkString(",")).mkString("|"))
Output:
1,2,3|1,3,2|2,1,3|2,3,1|3,1,2|3,2,1
Note that this is very inefficient though, because of all the list concatenations. An efficient solution would be tail-recursive or iterative. I'll post that a bit later for you.
I'm trying to write a functional approach in scala to get a list of all numbers between 1 & 1000 that are divisible by 3 or 5
Here is what I have so far :
def getListOfElements(): List[Int] = {
val list = List()
for (i <- 0 until 1000) {
//list.
}
list match {
case Nil => 0
}
list
}
The for loop seems like an imperative approach and I'm not sure what to match on in the case class. Some guidance please ?
Here's how I would do it with a for expression.
for( i <- 1 to 1000 if i % 3 == 0 || i % 5 == 0) yield i
This gives:
scala.collection.immutable.IndexedSeq[Int] = Vector(3, 5, 6, 9, 10, 12, 15, 18, 20, 21...
Here's another approach filtering on a Range of numbers.
scala> 1 to 1000
res0: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10...
scala> res0.filter(x => x % 3 == 0 || x % 5 == 0)
res1: scala.collection.immutable.IndexedSeq[Int] = Vector(3, 5, 6, 9, 10, 12, 15, 18, 20, 21...
If you really want a List on the return value use toList. e.g. res0.toList.
(Range(3, 1000, 3) ++ Range(5, 1000, 5)).toSet.toList.sorted
Sorted can be omitted.
another aproach:
(1 to 1000).filter(i => i % 3 == 0 || i % 5 == 0)
Looks like Brian beat me to it :)
Just thought I'd mention that a Stream might be more preferable here for better performance:
val x = (1 until 1000).toStream //> x : scala.collection.immutable.Stream[Int] = Stream(1, ?)
x filter (t=>(t%3==0)||(t%5==0)) //> res0: scala.collection.immutable.Stream[Int] = Stream(3, ?)
The problem from projecteuler.net also wants a sum of those numbers at the end.
"Find the sum of all the multiples of 3 or 5 below 1000."
object prb1 {
def main(args: Array[String]) {
val retval = for{ a <- 1 to 999
if a % 3 == 0 || a % 5 == 0
} yield a
val sum = retval.reduceLeft[Int](_+_)
println("The sum of all multiples of 3 and 5 below 1000 is " + sum)
}
}
The correct answer should be 233168
No any answer without division or list recreation. No any answer with recursion.
Also, any benchmarking?
#scala.annotation.tailrec def div3or5(list: Range, result: List[Int]): List[Int] = {
var acc = result
var tailList = list
try {
acc = list.drop(2).head :: acc // drop 1 2 save 3
acc = list.drop(4).head :: acc // drop 3 4 save 5
acc = list.drop(5).head :: acc // drop 5 save 6
acc = list.drop(8).head :: acc // drop 6 7 8 save 9
acc = list.drop(9).head :: acc // drop 9 save 10
acc = list.drop(11).head :: acc // drop 10 11 save 12
acc = list.drop(14).head :: acc // drop 12 13 14 save 15
tailList = list.drop(15) // drop 15
} catch {
case e: NoSuchElementException => return acc // found
}
div3or5(tailList, acc) // continue search
}
div3or5(Range(1, 1001), Nil)
EDIT
scala> val t0 = System.nanoTime; div3or5(Range(1, 10000001), Nil).toList;
(System.nanoTime - t0) / 1000000000.0
t0: Long = 1355346955285989000
res20: Double = 6.218004
One of answers that looks good to me:
scala> val t0 = System.nanoTime; Range(1, 10000001).filter(i =>
i % 3 == 0 || i % 5 == 0).toList; (System.nanoTime - t0) / 1000000000.0
java.lang.OutOfMemoryError: Java heap space
Another one:
scala> val t0 = System.nanoTime; (Range(1, 10000001).toStream filter (
(t: Int)=>(t%3==0)||(t%5==0))).toList ; (System.nanoTime - t0) / 1000000000.0
java.lang.OutOfMemoryError: Java heap space
First one:
scala> val t0 = System.nanoTime; (for( i <- 1 to 10000000 if i % 3 == 0 ||
i % 5 == 0) yield i).toList; (System.nanoTime - t0) / 1000000000.0
java.lang.OutOfMemoryError: Java heap space
Why Scala does not optimize for example Vector -> List?