Time/Space-Complexity method - time-complexity

I got a question to answer with the best complexity we can think about.
We got one sorted array (int) and X value. All we need to do is to find how many places in the array equals the X value.
This is my solution to this situation, as i don't know much about complexity.
All i know is that better methods are without for loops :X
class Question
{
public static int mount (int [] a, int x)
{
int first=0, last=a.length-1, count=0, pointer=0;
boolean found=false, finish=false;
if (x < a[0] || x > a[a.length-1])
return 0;
while (! found) **//Searching any place in the array that equals to x value;**
{
if ( a[(first+last)/2] > x)
last = (first+last)/2;
else if ( a[(first+last)/2] < x)
first = (first+last)/2;
else
{
pointer = (first+last)/2;
count = 1;
found = true; break;
}
if (Math.abs(last-first) == 1)
{
if (a[first] == x)
{
pointer = first;
count = 1;
found = true;
}
else if (a[last] == x)
{
pointer = last;
count = 1;
found = true;
}
else
return 0;
}
if (first == last)
{
if (a[first] == x)
{
pointer = first;
count = 1;
found = true;
}
else
return 0;
}
}
int backPointer=pointer, forwardPointer=pointer;
boolean stop1=false, stop2= false;
while (!finish) **//Counting the number of places the X value is near our pointer.**
{
if (backPointer-1 >= 0)
if (a[backPointer-1] == x)
{
count++;
backPointer--;
}
else
stop1 = true;
if (forwardPointer+1 <= a.length-1)
if (a[forwardPointer+1] == x)
{
count++;
forwardPointer++;
}
else
stop2 = true;
if (stop1 && stop2)
finish=true;
}
return count;
}
public static void main (String [] args)
{
int [] a = {-25,0,5,11,11,99};
System.out.println(mount(a, 11));
}
}
The print command count it right and prints "2".
I just want to know if anyone can think about better complexity for this method.
Moreover, how can i know what is the time/space-complexity of the method?
All i know about time/space-complexity is that for loop is O(n). I don't know how to calculate my method complexity.
Thank a lot!
Editing:
This is the second while loop after changing:
while (!stop1 || !stop2) //Counting the number of places the X value is near our pointer.
{
if (!stop1)
{
if ( a[last] == x )
{
stop1 = true;
count += (last-pointer);
}
else if ( a[(last+forwardPointer)/2] == x )
{
if (last-forwardPointer == 1)
{
stop1 = true;
count += (forwardPointer-pointer);
}
else
forwardPointer = (last + forwardPointer) / 2;
}
else
last = ((last + forwardPointer) / 2) - 1;
}
if (!stop2)
{
if (a[first] == x)
{
stop2 = true;
count += (pointer - first);
}
else if ( a[(first+backPointer)/2] == x )
{
if (backPointer - first == 1)
{
stop2 = true;
count += (pointer-backPointer);
}
else
backPointer = (first + backPointer) / 2;
}
else
first = ((first + backPointer) / 2) + 1;
}
}
What do you think about the changing? I think it would change the time complexity to O(long(n)).

First let's examine your code:
The code could be heavily refactored and cleaned (which would also result in more efficient implementation, yet without improving time or space complexity), but the algorithm itself is pretty good.
What it does is use standard binary search to find an item with the required value, then scans to the back and to the front to find all other occurrences of the value.
In terms of time complexity, the algorithm is O(N). The worst case is when the entire array is the same value and you end up iterating all of it in the 2nd phase (the binary search will only take 1 iteration). Space complexity is O(1). The memory usage (space) is unaffected by growth in input size.
You could improve the worst case time complexity if you keep using binary search on the 2 sub-arrays (back & front) and increase the "match range" logarithmically this way. The time complexity will become O(log(N)). Space complexity will remain O(1) for the same reason as before.
However, the average complexity for a real-world scenario (where the array contains various values) would be very close and might even lean towards your own version.

Related

How do I add to my int variables when I press a key?

The title summed up what I am trying to figure out.
I am trying to get my int variables to increase and/or decrease depending on what directional key I press.
int x;
int y;
x = 0;
y = 0;
Console.WriteLine("X:" +x + "Y:" +y);
while (Console.Readkey().Key == ConsoleKey.UpArrow)
{
y = +1;
}
If I press the Up arrow nothing happens, if I press any other directional keys it will exit the Console. I fell that I am on the right track because of that alone.
Any help is awesome.
Here you go. I've written this in a way that I'm assuming does what you want it to do.
int x = 0;
int y = 0;
while (true)
{
Console.WriteLine("X:" + x + "Y:" + y);
ConsoleKey key = Console.ReadKey().Key;
Console.Clear();
if (key == ConsoleKey.UpArrow)
{
y += 1;
}
else if (key == ConsoleKey.DownArrow)
{
y -= 1;
}
else if (key == ConsoleKey.RightArrow)
{
x += 1;
}
else if (key == ConsoleKey.LeftArrow)
{
x -= 1;
}
}
It saves the current key in ConsoleKey key and then checks which direction was pressed, and modifies x or y as necessary.
Note that I also added a Console.Clear() so everything prints neatly instead of repeatedly one after another.
Brackets {} should appear after a while statement, and the k in "Readkey" should be capitalized (e.g. "ReadKey")
while (Console.ReadKey().Key == ConsoleKey.UpArrow)
{
y = +1;
}
Edit: There was as semi-colon after the while statement, making the loop null. This version should work.

How to write test cases using Equivalence Class, Boundary value, and Basis Path Testing

I have a method isPerfect(x) (with 4<=x<=10000) below, how to write test cases based on Equivalence Class, Boundary Value, and Basis Path Testing:
public boolean checkPerfectNumber(int x) {
if(x >= 4 && x <= 10000) {
int sum = 0;
for(int i = 1; i < x; i++) {
if(x % i == 0) {
sum += i;
}
}
if(sum == x) return true;
}
return false;
}

how to increase the size limit of a mutable list in kotlin?

I was attempting to solve the multiset question (https://codeforces.com/contest/1354/problem/D) on codeforces using Fenwick Tree Data structure. I passed the sample test cases but got the memory limit error after submitting, the testcase is mentioned below.
(Basically the testcase is:
1000000 1000000
1.............1 //10^6 times
-1...........-1 //10^6 times).
I tried similar testcase in my IDE and got the below mentioned error.
(Similar to above, the testcase I provided is:
1000000 1
1.............1 //10^6 times
-1
)
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 524289 out of bounds for length 524289
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
at java.base/java.util.Objects.checkIndex(Objects.java:373)
at java.base/java.util.ArrayList.get(ArrayList.java:426)
at MultisetKt.main(multiset.kt:47)
at MultisetKt.main(multiset.kt)
Here is my code:
private fun readInt() = readLine()!!.split(" ").map { it.toInt() }
fun main() {
var (n, q) = readInt()
var list = readInt() //modify the list to store it from index 1
var finalList = listOf(0) + list
val query = readInt()
var bit = MutableList(n+1){0}
fun update(i:Int, value:Int) {
var index = i
while(index < n){
bit.set (index , bit[index] + value)
index += (index and -index)
}
}
fun rangefunc(i:Int): Int {
var su = 0
var index = i
while(index > 0){
su += bit[index]
index -= (index and -index)
}
return su
}
fun find(x:Int):Int {
var l = 1
var r = n
var ans = n
var mid = 0
while (l <= r) {
mid = (l + r) / 2
if (rangefunc(mid) >= x) {
ans = mid
r = mid - 1
} else {
l = mid + 1
}
}
return ans
}
for (i in 1..n) {
update(finalList[i], 1)
}
for (j in 0..q - 1) {
if (query[j] > 0) {
update(query[j], 1)
} else {
update(find(-query[j]), -1)
}
}
if(rangefunc(n) == 0){
println(0)
}else{
println(find(1))
}
}
I believe this is because the BITlist is not able to store 10^6 elements but not sure. Please let me know what changes should I make in my code also any additional advice on how to deal with such cases in the future.
Thank you in advance :)
An ArrayList can store over 2 billion items (2 * 10^9). That is not your issue. ArrayIndexOutOfBoundsException is for trying to access an index of an ArrayList that is less than zero or greater than or equal to its size. In other words, an index that it doesn't yet contain.
There's more code there than I have time to debug. But I would start at the line that the stack trace points to and see how it's possible for you to attempt to call bit[index] with an index that equals the size of the ArrayList.
To answer your literal question, you can use LinkedList explicitly as your type of MutableList to avoid the size restriction, but it is heavier and it is slower when accessing elements by index.

what's the stack space of this code?

The question is to check if a Tree is a valid BST. There are two recursive method to solve. I think their space complexity both are O(logN), N is the number of TreeNode, so logN is actually the height of tree. But in a solution book, it said the stack space is O(N), I can't figure out. Could anyone help me? Thanks!
public class Solution {
public boolean isValidBST(TreeNode root) {
return isValidBST(root, null, null);
}
private boolean isValidBST(TreeNode x, Integer min, Integer max) {
return x == null || (min == null || x.val > min) && (max == null || x.val < max) &&
isValidBST(x.left, min, x.val) && isValidBST(x.right, x.val, max);
}
}
public class Solution {
private TreeNode prev;
public boolean isValidBST(TreeNode root) {
prev = null;
return isMonotonicIncreasing(root);
}
private boolean isMonotonicIncreasing(TreeNode p) {
if (p == null) return true;
if (isMonotonicIncreasing(p.left)) {
if (prev != null && p.val <= prev.val) return false;
prev = p;
return isMonotonicIncreasing(p.right);
}
return false;
}
}
Space requirements will be O(h), where h is the height of the tree.
Log(n) is the best case for this code when the tree is balanced.
But in case of skewed trees the space complexity will be O(n) i.e. linear.
For example, for following trees, the code will take Exactly S(n) space:
1 5
2 4
3 3
4 2
5 1

I'm trying to figure out how to calculate if a number is prime or not [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
ive refined it a bit. Can someone change it to the correct way for me?
i also introduced a new variable isPrime i guess this is a bit better
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
#autoreleasepool {
int p = 7;
int d, isPrime = 0;
if (p % 2 != 0)
{
for (d = 2; d < p; d++) {
p % d;
}
if (p % d == 0)
{
isPrime = 1; //not prime
}
if (p % d != 0)
{
isPrime = 2; //is prime
}
if (isPrime == 1)
{
NSLog(#"its not prime");
}
if (isPrime == 2) {
NSLog(#"its prime");
}
}
else
NSLog(#"sorry");
}
return 0;
}
There's the well-known Sieve of Eratosthenes, but if you are writing a program that is just going to take one number as input and decide whether it's prime, the Sieve does more than you need (it finds all primes less than some value of your choice) so it may not be your most efficient choice of algorithm.
A couple other things about finding primes:
If you find that p is not even, you only have to try dividing it by odd numbers, that is, 3, 5, 7, 9, etc. (Yes, once you know it's not divisible by 3, technically you know it's not divisible by 9, but it may not be worthwhile or even efficient to account for such things in your algorithm.)
You don't have to try anything larger than sqrt(p) as a divisor. If you haven't found a divisor by then, you never will (except for 1 and p itself).
If you find a number that divides p, you can say immediately that p is not prime. (You might want to make sure you exit any loops then, too, otherwise you might end up printing the announcement that p is not prime more than once.)
... But you must never say that p is prime until the end of your algorithm, after all loops have completed. Until then, the most you can say is you haven't yet found a proof that p is not prime.
Above loop is fine , but you have to start from 3 rather than 2.
This is pseudo code for prime number calculation :
int num = 11;
NSString * res = null;
for(int i = 2 ;i<num ;i ++)
{
if(num%i == 0)
{
res = #"This is not a prime number";
break
}
else{
res = #"This is prime number";
}
}
try this
int p = 7;
int d, isPrime = 2;
if (p % 2 != 0)
{
for (d = 2; (d < p) && (isPrime == 2); d++) {
if (p % d == 0)
{
isPrime = 1; //not prime
}
if (p % d != 0)
{
isPrime = 2; //is prime
}
}
if (isPrime == 1)
{
NSLog(#"its not prime");
}
if (isPrime == 2) {
NSLog(#"its prime");
}
}
else
NSLog(#"sorry");