Time and space complexity of if(!areAllArrayElementsZero()) - algorithm

How can I calculate the time and space complexity of a program(pseudo code) as follows:
function(){
if(!areAllArrayElementsZero()){
if(hasAnyOdd()){
decreaseOneFromFirstOddElementInArray()
} else {
divideAllArrayElementByTwo()
}
}
}
Here areAllArrayElementsZero(),hasAnyOdd(),divideAllArrayElementByTwo() has the complexity O(n). Any leads would help. Actually I was designing the solution to this problem.
Here is the Java equivalent of the above pseudo code, I've designed:
package competitive;
/*
* Problem: http://www.geeksforgeeks.org/count-minimum-steps-get-given-desired-array/
*/
class formarray{
private static int[] elem;
private static boolean areAllZeros(){
for(int i=0; i<elem.length;i++){
if(elem[i]>0){
return false;
}
}
return true;
}
private static boolean hasAnyOdd(){
for(int i=0; i<elem.length;i++){
if(elem[i]%2 != 0){
// odd element discovered
return true;
}
}
return false;
}
private static boolean decreaseFirstOddByOne(){
for(int i=0; i<elem.length;i++){
if(elem[i]%2 != 0) {
// odd element discovered
elem[i]-=1;
// return true if one is decreased from first odd element
return true;
}
}
return false;
}
private static void DivideArrayElementsByTwo(){
for(int i=0; i<elem.length;i++){
// we are not checking element to be even as it has already been checked
elem[i] = elem[i]/2;
}
}
public static void main(String args[]){
elem = new int[args.length];
// assign values
for(int i=0;i<args.length;i++){
elem[i] = Integer.parseInt(args[i]);
}
int steps=0;
while(!areAllZeros()){
if(hasAnyOdd()){
// the array has odd members
if(decreaseFirstOddByOne()){
steps++;
}
} else {
DivideArrayElementsByTwo();
steps++;
}
}
System.out.println("Total steps required: "+steps);
}
}

There are exactly 4 paths of execution; sum up the cost of each, take the largest.
Or realize there are no loops and each path has a finite number of O(n) elements, making the whole thing O(n).

Related

Knight's tour Problem - storing the valid moves then iterating

I tried to code the knight's tour problem(8X8 board), but somehow I am not able to get it to work.
Instead of exploring all possible knight moves, I am storing it and iterating it one by one but
the program gets terminated before printing the result.
tagged the buggy code and (shamelessly copied) working code in comments.
Thanks in advance :)
*if the board is traversed, print answer and return
* find all possible moves from given position
* for everyPosition in possiblePosition
* place the knight at everyPosition
* call the same function for the new position
* remove the knight from that position
import java.util.*;
import java.util.Map.Entry;
class Solution {
static int [][] res;
static int N;
static int row[];
static int col[];
public static void init(int n) { //initialize the array
res=new int[n][n];//n or N is the size of board which is 8
N=n;
for(int i=0;i<res.length;i++) {
for(int j=0;j<res[0].length;j++) {
res[i][j]=-1;
}
}
}
public static void print(int[][] res) { //helper function to print the 2d array
for(int i=0;i<res.length;i++) {
for(int j=0;j<res[0].length;j++) {
System.out.print(res[i][j]+" ");
}
System.out.println();
}
System.out.println();
}
static boolean isValid(int r,int c){//check if the knight's move is inside the board then return true(<8 && >0)
return (r>=0 && c>=0 && r<N && c<N && res[r][c] == -1);
}
public static boolean solve(int a,int b,int sizeOfBoard,int count,int row[],int col[]) {
if(count==64)//if the board is traversed
{
System.out.println(":)");
print(res);
return true;
}
//**buggy code start**
ArrayList<ArrayList<Integer>>possibleKnightMoves=possibleKnightMoves(a,b,sizeOfBoard);
for(int i=0;i<possibleKnightMoves.size();i++) {//iterate over every possible knight move and check if the knight can be placed there or not
possibleKnightMoves=possibleKnightMoves(a,b,sizeOfBoard);
int x= possibleKnightMoves.get(i).get(0);
int y= possibleKnightMoves.get(i).get(1);
if(isValid(x,y)) {
res[x][y]=count;
if(solve(x,y,sizeOfBoard,count+1,row,col)) {
return true;
}else
{res[x][y]=-1;
}
}
}
//**buggy code end**
//**perfect working code, uncomment me and comment the buggy code(only for reference)**
// for(int i=0;i<N;i++) {
// int x=a+row[i];
// int y=b+col[i];
// if(isValid(x,y)) {
// res[x][y]=count;
// if(solve(x,y,sizeOfBoard,count+1,row,col))
// return true;//knight can be placed
// else
// res[x][y]=-1;
//
// }
//
// }
//**perfect working code end**
return false;//knight cant be placed at the square
}
public static ArrayList<ArrayList<Integer>> possibleKnightMoves(int a,int b,int sizeOfBoard) {
int x=a;
int y=b;
ArrayList<ArrayList<Integer>> result= new ArrayList<ArrayList<Integer>>();
for(int i=0;i<N;i++) {
x=x+row[i];// x,y represent all the possible knight moves from knight's current position
y=y+col[i];
result.add(new ArrayList<Integer>(Arrays.asList(x,y)));//add the moves to all possible moves list
}
return result;
}
public static void knightTour(int n) {
init(n);
res[0][0]=0;//set starting position
int array[]={2, 1, -1, -2, -2, -1, 1, 2 };//array 1 and array 2 represent the set of knight moves from (x,y) eg: x+2,y+1
row=array;
int array2[]={1, 2, 2, 1, -1, -2, -2, -1 };
col=array2;
solve(0,0,n,1,array,array2);//starting from 0,0 with count =1 as knight is already paced on 0,0
}
public static void main(String args[]) {
N=8;
knightTour(8);
init(8);
res[3][3]=1;
}
}
The problem is possibleKnightMoves method, where you wrote
for(int i=0;i<N;i++) {
x=x+row[i];current position
y=y+col[i];
result.add(new ArrayList<Integer>(Arrays.asList(x,y)));
}
Should be
for(int i=0;i<N;i++) {
x=a+row[i];//Changed here
y=b+col[i];//and here
result.add(new ArrayList<Integer>(Arrays.asList(x,y)));
}
Or else, the value of x and y adds on.
It is right now, but there is still one problem: your code runs too slow.
Consider this line
ArrayList<ArrayList<Integer>>possibleKnightMoves=possibleKnightMoves(a,b,sizeOfBoard);
And this line in the for loop:
possibleKnightMoves=possibleKnightMoves(a,b,sizeOfBoard);
You repeated doing the same thing several times, which if you just remove the line in the for loop, the result won't change but runs faster. So I think this is what you want:
import java.util.*;
import java.util.Map.Entry;
public class Main {
static int [][] res;
static int N;
static int row[];
static int col[];
public static void init(int n) { //initialize the array
res=new int[n][n];//n or N is the size of board which is 8
N=n;
for(int i=0;i<res.length;i++) {
for(int j=0;j<res[0].length;j++) {
res[i][j]=-1;
}
}
}
public static void print(int[][] res) { //helper function to print the 2d array
for(int i=0;i<res.length;i++) {
for(int j=0;j<res[0].length;j++) {
if(res[i][j] == -1) {
System.out.print("n ");
}else {
System.out.print(res[i][j]+" ");
}
}
System.out.println();
}
System.out.println();
}
static boolean isValid(int r,int c){//check if the knight's move is inside the board then return true(<8 && >0)
return (r>=0 && c>=0 && r<N && c<N && res[r][c] == -1);
}
public static boolean solve(int a,int b,int sizeOfBoard,int count,int row[],int col[]) {
if(count==64){
System.out.println(":)");
print(res);
return true;
}
ArrayList<ArrayList<Integer>>possibleKnightMoves=possibleKnightMoves(a,b,sizeOfBoard);
for(int i=0;i<possibleKnightMoves.size();i++) {//iterate over every possible knight move and check if the knight can be placed there or not
int x= possibleKnightMoves.get(i).get(0);
int y= possibleKnightMoves.get(i).get(1);
if(isValid(x,y)) {
res[x][y]=count;
if(solve(x,y,sizeOfBoard,count+1,row,col)) {
return true;
}else{
res[x][y]=-1;
}
}
}
return false;//knight cant be placed at the square
}
public static ArrayList<ArrayList<Integer>> possibleKnightMoves(int a,int b,int sizeOfBoard) {
ArrayList<ArrayList<Integer>> result= new ArrayList<ArrayList<Integer>>();
for(int i=0;i<N;i++) {
int x=a+row[i];//Changed here
int y=b+col[i];//and here
result.add(new ArrayList<Integer>(Arrays.asList(x,y)));
}
return result;
}
public static void knightTour(int n) {
init(n);
res[0][0]=0;//set starting position
int array[]={2, 1, -1, -2, -2, -1, 1, 2 };//array 1 and array 2 represent the set of knight moves from (x,y) eg: x+2,y+1
row=array;
int array2[]={1, 2, 2, 1, -1, -2, -2, -1 };
col=array2;
solve(0,0,n,1,array,array2);//starting from 0,0 with count =1 as knight is already paced on 0,0
}
public static void main(String args[]) {
N=8;
knightTour(8);
init(8);
res[3][3]=1;
}
}

Path exists between cities or not

The link to the problem is Q4 Traveling is Fun.
I can only think of a brute force approach to compute every possible gcd and run bfs from source to destination to check if there exists a path or not.
But the above approach gives TLE in 5 test cases.
Can anyone provide a more efficient approach ?
This is a quick implementation of the graph structure I would use:
class GCDGraph {
private Map<Integer, Set<Integer>> adj = new HashMap<>();
public GCDGraph(int g, int[] srcCities, int[] dstCities){
int n = srcCities.length;
for(int i=0;i<n;i++){
adj.put(i, new HashSet<>());
}
for(int i=0;i<n;i++){
for(int j=0;j<i;j++){
int gtmp = gcd(srcCities[i], dstCities[j]);
if(gtmp > g){
adj.get(i).add(j);
adj.get(j).add(i);
}
}
// we could add the connection i -> i (assuming srcCities[i] > g)
// but that would not help us find a path, as it introduces a cycle
}
}
private int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }
public Set<Integer> adjacentVertices(int vertex){ return adj.get(vertex); }
public int size(){ return adj.size(); }
public boolean isEmpty(){ return size() == 0; }
public boolean hasPath(int src, int dst){
return buildPath(src, dst, new HashSet<>());
}
private boolean buildPath(int src, int dst, Set<Integer> tmp){
if(src == dst){
return true;
} else {
for(int nextVertex : adjacentVertices(src)){
if(tmp.contains(nextVertex))
continue;
tmp.add(nextVertex);
if(buildPath(nextVertex, dst, tmp))
return true;
tmp.remove(nextVertex);
}
}
return false;
}
}
It explicitly stores the adjacency as a Map (allowing fast lookup).
It has some utility methods (size, isEmpty).
It only looks up the GCD when it is being built, and only once for each x/y pair.
And it uses recursion to perform BFS, quitting as soon as possible.

Insertion Sort for Singly Linked List [EXTERNAL]

I'm not sure where to start, but this is messy. Basically I need to write an Insertion Sort method for singly linked list - which causes enough problems, because usually for Insertion Sort - you're supposed to go through array/list elements backwards - which implementing into a singly linked list seems pointless, because the point of it - is that you're only capable of going forwards in the list and in addition to that -> I need to execute "swap" operations externally, which I do not completely understand how to perform that while using list structure.
This is my ArrayClass and Swap method that I used:
class MyFileArray : DataArray
{
public MyFileArray(string filename, int n, int seed)
{
double[] data = new double[n];
length = n;
Random rand = new Random(seed);
for (int i = 0; i < length; i++)
{
data[i] = rand.NextDouble();
}
if (File.Exists(filename)) File.Delete(filename);
try
{
using (BinaryWriter writer = new BinaryWriter(File.Open(filename,
FileMode.Create)))
{
for (int j = 0; j < length; j++)
writer.Write(data[j]);
}
}
catch (IOException ex)
{
Console.WriteLine(ex.ToString());
}
}
public FileStream fs { get; set; }
public override double this[int index]
{
get
{
Byte[] data = new Byte[8];
fs.Seek(8 * index, SeekOrigin.Begin);
fs.Read(data, 0, 8);
double result = BitConverter.ToDouble(data, 0);
return result;
}
}
public override void Swap(int j, double a)
{
Byte[] data = new Byte[16];
BitConverter.GetBytes(a).CopyTo(data, 0);
fs.Seek(8 * (j + 1), SeekOrigin.Begin);
fs.Write(data, 0, 8);
}
}
And this is my Insertion Sort for array:
public static void InsertionSort(DataArray items)
{
double key;
int j;
for (int i = 1; i < items.Length; i++)
{
key = items[i];
j = i - 1;
while (j >= 0 && items[j] > key)
{
items.Swap(j, items[j]);
j = j - 1;
}
items.Swap(j, key);
}
}
Now I somehow have to do the same exact thing - however using Singly Linked List, I'm given this kind of class to work with (allowed to make changes):
class MyFileList : DataList
{
int prevNode;
int currentNode;
int nextNode;
public MyFileList(string filename, int n, int seed)
{
length = n;
Random rand = new Random(seed);
if (File.Exists(filename)) File.Delete(filename);
try
{
using (BinaryWriter writer = new BinaryWriter(File.Open(filename,
FileMode.Create)))
{
writer.Write(4);
for (int j = 0; j < length; j++)
{
writer.Write(rand.NextDouble());
writer.Write((j + 1) * 12 + 4);
}
}
}
catch (IOException ex)
{
Console.WriteLine(ex.ToString());
}
}
public FileStream fs { get; set; }
public override double Head()
{
Byte[] data = new Byte[12];
fs.Seek(0, SeekOrigin.Begin);
fs.Read(data, 0, 4);
currentNode = BitConverter.ToInt32(data, 0);
prevNode = -1;
fs.Seek(currentNode, SeekOrigin.Begin);
fs.Read(data, 0, 12);
double result = BitConverter.ToDouble(data, 0);
nextNode = BitConverter.ToInt32(data, 8);
return result;
}
public override double Next()
{
Byte[] data = new Byte[12];
fs.Seek(nextNode, SeekOrigin.Begin);
fs.Read(data, 0, 12);
prevNode = currentNode;
currentNode = nextNode;
double result = BitConverter.ToDouble(data, 0);
nextNode = BitConverter.ToInt32(data, 8);
return result;
}
To be completely honest - I'm not sure neither how I'm supposed to implement Insertion Sort nor How then translate it into an external sort. I've used this code for not external sorting previously:
public override void InsertionSort()
{
sorted = null;
MyLinkedListNode current = headNode;
while (current != null)
{
MyLinkedListNode next = current.nextNode;
sortedInsert(current);
current = next;
}
headNode = sorted;
}
void sortedInsert(MyLinkedListNode newnode)
{
if (sorted == null || sorted.data >= newnode.data)
{
newnode.nextNode = sorted;
sorted = newnode;
}
else
{
MyLinkedListNode current = sorted;
while (current.nextNode != null && current.nextNode.data < newnode.data)
{
current = current.nextNode;
}
newnode.nextNode = current.nextNode;
current.nextNode = newnode;
}
}
So if someone could maybe give some kind of tips/explanations - or maybe if you have ever tried this - code examples how to solve this kind of problem, would be appreciated!
I actually have solved this fairly recently.
Here's the code sample that you can play around with, it should work out of the box.
public class SortLinkedList {
public static class LinkListNode {
private Integer value;
LinkListNode nextNode;
public LinkListNode(Integer value, LinkListNode nextNode) {
this.value = value;
this.nextNode = nextNode;
}
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
public LinkListNode getNextNode() {
return nextNode;
}
public void setNextNode(LinkListNode nextNode) {
this.nextNode = nextNode;
}
#Override
public String toString() {
return this.value.toString();
}
}
public static void main(String...args) {
LinkListNode f = new LinkListNode(12, null);
LinkListNode e = new LinkListNode(11, f);
LinkListNode c = new LinkListNode(13, e);
LinkListNode b = new LinkListNode(1, c);
LinkListNode a = new LinkListNode(5, b);
print(sort(a));
}
public static void print(LinkListNode aList) {
LinkListNode iterator = aList;
while (iterator != null) {
System.out.println(iterator.getValue());
iterator = iterator.getNextNode();
}
}
public static LinkListNode sort(LinkListNode aList){
LinkListNode head = new LinkListNode(null, aList);
LinkListNode fringePtr = aList.getNextNode();
LinkListNode ptrBeforeFringe = aList;
LinkListNode findPtr;
LinkListNode prev;
while(fringePtr != null) {
Integer valueToInsert = fringePtr.getValue();
findPtr = head.getNextNode();
prev = head;
while(findPtr != fringePtr) {
System.out.println("fringe=" + fringePtr);
System.out.println(findPtr);
if (valueToInsert <= findPtr.getValue()) {
LinkListNode tmpNode = fringePtr.getNextNode();
fringePtr.setNextNode(findPtr);
prev.setNextNode(fringePtr);
ptrBeforeFringe.setNextNode(tmpNode);
fringePtr = ptrBeforeFringe;
break;
}
findPtr = findPtr.getNextNode();
prev = prev.getNextNode();
}
fringePtr = fringePtr.getNextNode();
if (ptrBeforeFringe.getNextNode() != fringePtr) {
ptrBeforeFringe = ptrBeforeFringe.getNextNode();
}
}
return head.getNextNode();
}
}
From a high level, what you are doing is you are keeping track of a fringe ptr, and you are inserting a node s.t. the it is in the correct spot in the corresponding sublist.
For instance, suppose I have this LL.
3->2->5->4
The first iteration, I have fringePtr at 2, and I want to insert 2 somewhere in the sublist that's before the fringe ptr, so I basically traverse starting from head going to the fringe ptr until the value is less than the current value. I also have a previous keeping track of the previous ptr (to account for null, I have a sentinel node at the start of my traversal so I can insert it at the head).
Then, when I see that it's less than the current, I know I need to insert it next to the previous, so I have to:
use a temporary ptr to keep track of my previous's current next.
bind previuos's next to my toInsert node.
bind my toInsert node's next to my temp node.
Then, to continue, you just advance your fringe ptr and try again, basically building up a sublist that is sorted as you move along until fringe hits the end.
i.e. the iterations will look like
1. 3->2->5->4
^
2. 2->3->5->4
^
3. 2->3->5->4
^
4. 2->3->4->5 FIN.

solving knapsack dynamic programming debugging

I tried to solve the classical knapsap problem myself. But I am getting a wrong answer as 108. Could you help me to figure out what I have done wrong. Here I am using recursion.
Weight limit is 10
answer is 5+3+2 ==> 25+15+14=54
public class KnapSack {
public static int[] weight={6,5,4,3,2};
public static int[] value={12,25,24,15,14};
public static void main(String[] args) {
System.out.println(c(0,0,10));
}
public static int c(int currentElement,int currentValue,int currentReamainder){
int p = 0;
if(currentReamainder<=0) return currentValue;
for(int i=currentElement;i<weight.length;i++){
if(currentReamainder<weight[i]) return currentValue;
p = Math.max(value[i]+c(i+1,currentValue+value[i],currentReamainder-weight[i]),c(i+1,currentValue,currentReamainder))
}
return p;
}
}
Update:
What should I do to print the weights of the optimum solution ?
Your error is this line
p=Math.max(value[i]+c(i+1,currentValue+value[i],currentReamainder-weight[i]),c(i+1,currentValue,currentReamainder));
it should be
int val = Math.max(value[i]+c(i+1,currentValue+value[i],currentReamainder-weight[i]),c(i+1,currentValue,currentReamainder));
p = Math.max(val, p);
The last bug is when you both updating currentValue and return p at the same time, so imagine the last call, when the function return currentValue, plus the last value[i] in each step, so your result is double
So , your function should be (notice I have removed the currentValue parameter, which is not necessary):
public static int c(int currentElement,int currentReamainder){
int p = 0;
if(currentReamainder<=0) return 0;
for(int i=currentElement;i<weight.length;i++){
if(currentReamainder<weight[i]) break;//This line is not valid, only when the weight array is sorted(ascending order)
int val = Math.max(value[i]+c(i+1,currentReamainder-weight[i]),c(i+1,currentReamainder));
p = Math.max(val, p);
}
return p;
}

A more effective algorithm

This is my first time posting question, do pardon me if anything I do is wrong.
My question here is how to get a faster algorithm from this code? i'm currently using 2 stacks to implement the code such that it will get the minimum value out of the range of index User asks for input.
Example (2,3,4,5,1), if (user selects (1,4)), it means they are looking at (2,3,4,5), which the output is 2.
Thanks.
import java.util.*;
interface StackADT <Integer> {
// check whether stack is empty
public boolean empty();
// retrieve topmost item on stack
public int peek() throws EmptyStackException;
// remove and return topmost item on stack
public int pop() throws EmptyStackException;
// insert item onto stack
public void push(int item);
}
class StackArr <Integer> implements StackADT <Integer> {
private int[] arr;
private int top;
private int maxSize;
private final int INITSIZE = 1000;
public StackArr() {
arr = (int[]) new int[INITSIZE]; // creating array of type E
top = -1; // empty stack - thus, top is not on an valid array element
maxSize = INITSIZE;
}
public boolean empty() {
return (top < 0);
}
public int peek() throws EmptyStackException {
if (!empty()) return arr[top];
else throw new EmptyStackException();
}
public int pop() throws EmptyStackException {
int obj = peek();
top--;
return obj;
}
public void push(int obj) {
if (top >= maxSize - 1) enlargeArr();
top++;
arr[top] = obj;
}
}
class RMQ{
//declare stack object
Stack<Integer> stack1;
public RMQ(){
stack1 = new Stack<Integer>();
}
public void insertInt(int num){
stack1.push(num);
}
public int findIndex(int c, int d){
Stack<Integer> tempStack = new Stack<Integer>();
Stack<Integer> popStack = new Stack<Integer>();
tempStack = (Stack)stack1.clone();
while (d != tempStack.size())
{
tempStack.pop();
}
int minValue = tempStack.pop();
popStack.push(minValue);
while (c <= tempStack.size())
{
int tempValue = tempStack.pop();
if(tempValue >= minValue)
{
continue;
}
else
{
popStack.push(tempValue);
minValue = tempValue;
}
}
return popStack.pop();
}
}
public class Pseudo{
public static void main(String[] args){
//declare variables
int inputNum;
int numOfOperations;
//create object
RMQ rmq = new RMQ();
Scanner sc = new Scanner(System.in);
//read input
inputNum = sc.nextInt();
//add integers into stack
for(int i=0; i < inputNum; i++){
rmq.insertInt(sc.nextInt());
}
// read input for number of queries
numOfOperations = sc.nextInt();
// Output queries
for(int k=0; k < numOfOperations; k++){
int output = rmq.findIndex(sc.nextInt(), sc.nextInt());
System.out.println(output);
}
}
}
Why are you using a stack? Simply use an array:
int[] myArray = new int[inputNum];
// fill the array...
// get the minimum between "from" and "to"
int minimum = Integer.MAX_VALUE;
for(int i = from ; i <= to ; ++i) {
minimum = Math.min(minimum, myArray[i])
}
And that's it!
The way I understand your question is that you want to do some preprocessing on a fixed array that then makes your find min operation of a range of elements very fast.
This answer describes an approach that does O(nlogn) preprocessing work, followed by O(1) work for each query.
Preprocessing O(nlogn)
The idea is to prepare a 2d array SMALL[a,k] where SMALL[a,k] is the minimum of the 2^k elements starting at a
You can compute this array in a recursive way by starting at k==0 and then building up the value for each higher element by combining two previous elements together.
SMALL[a,k] = min(SMALL[a,k-1] , SMALL[a+2^(k-1),k-1])
Lookup O(1) per query
You are then able to instantly find the min for any range by combining 2 preprepared answers.
Suppose you want to find the min for elements from 100 to 133. You already know the min of 32 elements 100 to 131 (in BIG[100,5]) and also the min of 32 elements from 102 to 133 (in BIG[102,5]) so you can find the smallest of these to get the answer.
This is Range Minimum Query problem.
There are some algorthms and data structures to solve it effectively

Resources