How do I remove all "edges" from a node? - java

A question for my comp sci class goes like this:
We can represent a graph using an "adjacency matrix" int[][] matrix. matrix[i][j] will be non-zero if there is an edge FROM node i TO node j. In other words, node i considers node j to be its "neighbor" in this case. Note that this does not necessarily mean node j considers node i to be ITS neighbor, allowing for asymmetrical relationships. Each value could also be zero, indicating there is no edge/connection. The matrix will be n x n in size, where n is the number of nodes and nodes are numbered 0 to n-1, allowing any node to connect to any other node numbered within this range.
Given an adjacency matrix and int x, remove all edges to and from the node at index x.
I understand what an adjacency matrix is, but I don't understand what the problem means by edges, or what index x is.
My code so far looks like this:
public void removeEdgesFromNode(int[][] matrix, int x) {
for(int i = 0; i < matrix.length; i++) {
for(int j = 0; j < matrix[].length; j++) {
if(j == x || i == x) {
matrix[i, j] = 0;
}
}
}
}
There is an error occurring where it says
Compilation error on line 7: error: class expected
for(int j = 0; j < matrix[].length; j++) {
^
I don't think the way I'm solving the problem is correct, however I am attempting to start the problem at least.

The way you are solving the problem is correct, but not the most optimal.
The edges from x, would mean that matrix[x][j] would be 0 for each j.
The edges to x, would mean that matrix[i][x] would be 0 for each i.
In other words, all the elements matrix[i][j] where i or j are x, should be 0. Which is what you are doing.
First things first. Your error. matrix[].length should be matrix.length. Try your solution. It should work.
For the most optimal solution check Dariosicily answer. However with that one you need to make sure that the matrix is squared and x<n.
Your answer would go over every element of the matrix, so nxn= n^2 elements with complexity O(n^2), but his solution you only need to go over 2*n elements O(n), so when n is very big, you would notice the performance improvement. You can give it a try :)

You were close to the solution. Because you have a square n x n matrix and fixed an index x in the range 0 .. n - 1 you want to remove all elements staying in the xth row or in the xth column you can do it with one loop like below:
public static void removeEdgesFromNode(int[][] matrix, int x) {
int n = matrix.length;
for (int i = 0; i < n; ++i) {
matrix[i][x] = 0;
matrix[x][i] = 0;
}
}
If you use an x index equal or greater than n an ArrayIndexOutOfBoundsException exception will be thrown, it's up to you decide how to handle this scenario.

Related

How can I utilize merge sort approach to reduce running time of my program

I have a function that takes in an int[] array with the expectation that all elements are sorted from largest to smallest.
I want to find how many pairs violate this expectation ( a larger element x in the array is present AFTER a smaller element x + array.length() while not going out of bounds)
For instance,
if array = [7,3,5,4,1] the answer would be 2 because the pairs that violate the order are 3 and 5 and 3 and 4, since 3 is smaller than them and should've been ahead of them.
Here is my current code:
public static int countBad(int[] array){
int counter = 0;
for (int x = 0; x < array.length; x++){
for (int y = x + 1; y <= x + array.length && y < array.length; y++){
if(array[x] < array[x+y]){
counter++;
}
}
}
return counter;
}
Even though my code works, it is extremely inefficient, which is why I wish to reduce the time complexity. I've been told about a merge sort approach to this issue. However, I'm struggling to grasp how to convert my existing method into a merge sort approach.
Can anyone please help explain how to do this?

Matrix multiplication Big O notation

I have a question regarding best case scenario for this piece of code and worst case scenario in Big O notation. From my point of view, it should be O (n^3) for both cases but some people disagree.
public int [][] multiply (int [][] A, int
[][] B, int n) {
int [][] C = new int[n][n]; - 1 ( ignored )
for(int i=0; i<n; i++) { - n
for(int j=0; j<n; j++) { - n
if(A[i][j ]!=0) { - 1 ( ignored )
for (int k=0; k<n; k++) { - n
C[i][k] += A[i][j]*B[j][k]; -
}
}
}
}
return C;
}
It is true that matrix multiplication takes O(n^3) time to run in average and worst cases. For 2 matrices of dimensions m x n and n x p respectively, there is going to be a total of mnp (or n^3 for simplicity) calculations, one for each entry in the resultant matrix. As for the best case, it depends on what your program does when it sees that at least one of the matrices is a zero matrix (all entries in the matrix are 0). If it can spot a zero matrix, then you can short circuit the program. In this case, the running time is going to be O(n^2) (you just scan a couple of n x n matrices at most), which is the best that can be achieved for matrix multiplication. If this optimization is not available, the program will run in O(n^3) in any case. Either way, you can still say that the best case is O(n^3) because of the definition of Big-O notation, but that is not of interest to most people.
The line of code shown above must be corrected.
C[i][k] += A[i][j]*B[j][k];
It should be corrected as follows.
C[i][j] += A[i][k]*B[k][j];

Minimal calls to subArrayLeftShift method for sorting array (interview question)

Suppose you have a method subArrayLeftShift(a,i) which shifts left the sub array a[i,...,n-1] when n is the array length. That means that the elements a[i+1],...,a[n-1] are moving one place to the left, and the original a[i] will become the last one.
More formally, here is the function implementation:
public static void subArrayLeftShift(int[] a, int i){
if (a.length == 0) return;
int last = a.length - 1;
int insertToLast = a[i];
for (; i < last; i++){
a[i] = a[i + 1];
}
a[last] = insertToLast;
}
Now for the question: implement a function that receives an unsorted array, and returns the minimal number of calls to subArrayLeftShift for sorting the array.
In the interview I couldnt find the way to do it. I succeed to find the minimal number of calls for every example I wrote for intuition, but couldn't find a way for generalizing it.
Do you know how to solve it?
I propose the following algorithm to solve the problem:
Find the minimum number in the array that is not sorted ( has a smaller number on the right in the array). Let this number be x.
Count how many numbers in the array are greater than the previously found number x. Let this number be y.
Since for each call to the function, the unsorted number will end up at the last position, the optimum strategy is to call the function for each unsorted number in increasing order. Using what was found previously we start with x. We continue with the next unsorted number bigger than x, because in this way, it will end up on the right of x, hence it will be sorted. Continue in the same fashion. How much? How many bigger number than x we have? Well, that's y. So as a total, the number of calls to the function is 1 + y.
public static int minimumCalls(int[] a) {
int minCalls = 0;
for (int i = 0; i < a.length - 1; i++) {
for (int j = i+1; j < a.length; j++) {
if (a[i] > a[j]) {
minCalls++;
break;
}
}
}
return minCalls;
}
The idea behind my thinking is that you must invoke the method once whenever there exists in the SubArray any value less than the current i. The name of the method subArrayShiftLeft, i feel, is designed to throw you off and drag your attention away from thinking of this easily.
If there's any values less than the current one further on in the array, just invoke the method.
It's much easier to think of this as moving a single larger value to the end of the array than trying to shift the smaller ones to the left.

How to write this algorithm more efficiently

I have an assignment where I have to write an algorithm which 'splits' the array in two. Left side should be odd numbers, and right side should be even numbers. Both sides should be sorted in ascending order. I'm not allowed to use temp arrays or existing api.
I have managed to make a working method, problem is with an array of say 100 000 integers, it takes approximately 15 seconds to finish. The requirement is 0,1 seconds, so I obviously have a lot to improve. I'm not looking for someone to spoon-feed me the answer, just a nudge in the right direction. Please don't write any working code for me, though I would like to know if and why something I've written is bad!
What I have so far:
public static void delsortering(int[] a){
int oddnum = 0;
int n = a.length;
for(int k : a){ //finds how many odd numbers there are
if((k & 1) != 0) oddnum++;
}
for(int i = 0; i < n; i++){
if((a[i] & 1) != 0){ //finds odd numbers
for(int j = 0; j < n; j++){
if((a[j] & 1) == 0) //looks for even numbers to change pos with
switch(a, j, i);
}
}
}
for (int i = 0; i < n; i++){
int from = i < oddnum ? 0 : oddnum;
int to = i < oddnum ? oddnum - i: n - i + oddetall;
int m = maxValue(a, from, to); //finds max value in specified range
switch(a, m, to - 1); //puts said max value at specified index
}
}
Appreciate all the help I can get!
A better solution would be:
Firstly keep two variables that point to the first and last elements of the array e.g x=0; y=N-1.
Then start moving x to the right until you find an even number (all numbers until now are odd !!!), then start moving y to the left until you find an odd number (all number you examine while decreasing-moving left y are even until the first one odd you find !!!)
Swap values x,y ,increase x,y and repeat the same procedure until x,y get crossed.
Then you have the array with evens on the right and odd on the left but not ordered. So you could count during the above procedure the number of odds and evens in order to know where there are separated in the array let's say in k index.
Sort array[0 - k], Sort array[k+1 - N].
Complexity: O(n) for the first part (x,y are only once moving to one direction) and O(nlogn) for both sorts so O(nlogn) which is better than O(n^2) that is your solution.

Finding a minmuim swaps in an array

I have found a problem on a net for generating some sequence.
A = [A1, A2, ..., AN]
and
where A1 < A2 < ... < Am > Am+1 > ... > AN for some index m, with m between 1 and N inclusive).
I want to find the minimum swaps to accomplish this
For Ex
1 8 10 3 7
Swap between 3 and 7 will give me the required seq.
Ans=1
I found this code in the editorial:
boolean[] done = new boolean[n];
for(int i=0;i<n;i++) {
int index = -1;
for(int j=0;j<n;j++) {
if(!done[j] && (index == -1 || values[j] < values[index]))
index = j;
}
int left = 0, right = 0;
for(int j=0;j<index;j++)
if(!done[j])
left++;
for(int j=index+1;j<n;j++)
if(!done[j])
right++;
res += Math.min(left, right);
done[index] = true;
}
return res;
I can't understand the code what its doing How can i found the minimum swap ? Is this a standard algorithm question.And time complexity is O(n^2) is this good.
(Note: swap seems to mean swap of two adjacent elements.)
The idea behind the code is as follows. The minimum element x must be moved either to the first or last position in the array. The number of swaps to move x does not depend on which swaps not involving x are performed. For every valid solution, the swaps not involving x are a solution for the array with x removed. Thus, there exists an optimal solution that moves x to the first or last position and then recursively deals with the remaining elements.
The structure of the code is to find the minimum unprocessed element (inner loop 1; done[j] is a flag indicating whether the element at position j has been processed), determine how many swaps are needed to move it to the first position (inner loop 2), and determine how many swaps are needed to move it to the last position (inner loop 3). We don't count swaps over processed elements because, when we're moving the current element, those elements already have been moved out of the way.
The running time could be improved to O(n log n) by substituting merge sort for the implicit selection sort and using a Fenwick tree to count the number of unprocessed elements in a range.

Categories