I found this bubble sort (first sort I'm ever studying), I understand it almost fully but I'm stuck on one spot.
public static int[] bubbleSort(int[] tempArray) {
int i, j, temp, n = tempArray.length;
boolean swapped;
for (i = 0; i < n - 1; i++) {
swapped = false;
for (j = 0; j < n - i - 1; j++) {
if (tempArray[j] > tempArray[j + 1]) {
temp = tempArray[j];
tempArray[j] = tempArray[j + 1];
tempArray[j + 1] = temp;
swapped = true;
}
}
if (swapped == false)
break;
}
return tempArray;
}
what is the point of "n - 1" in outer loop besides helping to make inner loop (n - i - 1) shorter? I tried removing the "n -1" and having count++ to work in the inner loop and the result was the same, so what is the reason for it then? Thanks!
It is because the largest element is already sorted in the first iteration.
A picture is worth a thousand words
Image is from https://en.wikipedia.org/wiki/Bubble_sort
Additional there is no need for the last element because bubble sort is all about swapping adjacent element and the last element doesn't have adjacent element.
It is because bubble sorting works on swapping of adjacent element.
If outer loop goes till n then in the inner loop you cannot pick another element.
temp = tempArray[j];
tempArray[j] = tempArray[j + 1];
tempArray[j + 1] = temp;
This is because the size of array is till n and inner loop swap between j and j+1.
Feel free to ask further doubts.
I spend last 5 hours looking at so many videos and readings (cormen included) and i finally decided to write my own heapsort to test it out. I am basically taking some inputs from standard input and storing them in an array and then i will use heapsort to sort them.
Following is my code
public static void buildHeap(int[] A)
{
n = A.length - 1;
for(int i = n/2; i>0; i--)
{
maxHeapify(A,i);
}
}
public static void maxHeapify(int[] A, int i)
{
int left = 2*i;
int right = 2*i + 1;
int largest = 0;
if(left <= n && A[left] > A[i])
{
largest=left;
}
else
{
largest=i;
}
if(right <= n && A[right] > A[largest]){
largest=right;
}
if(largest!=i){
int temp = A[i];
A[i] = A[largest];
A[largest] = temp;
maxHeapify(A, largest);
}
}
My Array Input is : 3,5,8,7,1,13,11,15,6 Output is:
3,15,13,11,6,8,5,7,1
The output is obviously wrong as the first index should contain the highest value 15.
So then i decided to take the good old route of taking a pen and a notebook and tracing the code and realized that in the buildHeap the i should be n-1/2 . However it also did not give me the correct output. I am really lost now and frustrated. Can anyone shed light as to what i am doing wrong?
Your index calculations are off:
int left = 2*i;
int right = 2*i + 1;
If i is 0, then we want left and right to be 1 and 2. If i is 1, then left and right should be 3 and 4, and so on. The calculations should be:
int left = 2*i + 1;
int right = 2*i + 2;
Also,
for(int i = n/2; i>0; i--)
The condition is i > 0. The body of the loop will only run when i > 0, so the element at index 0 (i.e. the first one) won't get moved. The condition should be i >= 0.
I'm writing a program that finds the maximum number of paths a checker can take. It starts on the tiles in a board's starting row, and ends on the tiles in the board's ending row. The problem is that I am unable to figure out how to map the machine-readable tile labels to the human-readable tile labels.
1 2 3 4 A B
R|B|R|B R|B|R|B
B|R|B|R B|R|B|R
R|B|R|B R|B|R|B
B|R|B|R B|R|B|R
1 2 3 4 1 2
While my program is calculating paths, I want it to be able to see the board the way it is depicted on the left. However, while it is finding the end tile with the maximum number of paths, I want it to read the board the way it is depicted on the right. I'm thinking of having a "halved" array where each tile number is stored twice in a row. For example, it could be [1, 1, 2, 2] instead of [1, 2, 3, 4]. I'm just not sure how to implement this. Here is part of my program:
// place checker on each bottom-row black space, and count paths
for (int checkerPos = 1; checkerPos < rFringe; checkerPos += 2)
{ // always starts in bottom-left-hand corner
board = resetBoard(board); // clear board for new checker
board[bottomRow][checkerPos] = 1; // put checker on starting location
// calculate # of paths from starting location to each end tile
for (int r = bottomRow - 1; r > 0; r--) // start in row above bottom, and end right before top fringe (i.e. row 0)
{
for (int c = 1; c < rFringe; c++)
board[r][c] = board[r + 1][c - 1] + board[r + 1][c + 1];
}
// find end tile with max paths
max = board[1][1]; // default max is upper-left space on checkerboard
for (int c = 2; c < rFringe; c++) // don't re-check first column and don't check fringe
{
// compare this to other top-row boxes to find one with highest value
if (board[1][c] > max)
{
max = board[1][c];
startLoc = checkerPos; // GETS WRONG VALUE
endLoc = c; // GETS WRONG VALUE
}
}
maxInfo[maxCount] = max; // add current piece's max to max array
maxInfo[maxCount + 1] = startLoc; // save start location
maxInfo[maxCount + 2] = endLoc; // save end location
maxCount += 3; // go to next empty slot in array
}
As you can see, without a way to map checkerPos and c to startLoc and endLoc, I am unable to get accurate values for these variables.
To fix this problem, I implemented a "halved" array.
int[] halved = new int[size]; // used for mapping the machine-readable tile #s to human-readable tile #s and letters
// populate halved array
for (int halvedIdx = 0, i = 1; halvedIdx < size - 1; halvedIdx += 2, i++)
{
halved[halvedIdx] = i;
halved[halvedIdx + 1] = i;
}
In addition to this, I changed
startLoc = checkerPos;
endLoc = c;
to
startLoc = halved[checkerPos];
endLoc = halved[c];
I'm not sure if this is the best solution. If anyone has suggestions, feel free to comment.
UPDATE
A problem with this solution is that, if the board's size is odd, checkerPos ends up being outside of the halved array's bounds.
I'm trying to solve the edit distance problem. the code I've been using is below.
public static int minDistance(String word1, String word2) {
int len1 = word1.length();
int len2 = word2.length();
// len1+1, len2+1, because finally return dp[len1][len2]
int[][] dp = new int[len1 + 1][len2 + 1];
for (int i = 0; i <= len1; i++) {
dp[i][0] = i;
}
for (int j = 0; j <= len2; j++) {
dp[0][j] = j;
}
//iterate though, and check last char
for (int i = 0; i < len1; i++) {
char c1 = word1.charAt(i);
for (int j = 0; j < len2; j++) {
char c2 = word2.charAt(j);
//if last two chars equal
if (c1 == c2) {
//update dp value for +1 length
dp[i + 1][j + 1] = dp[i][j];
} else {
int replace = dp[i][j] + 1 ;
int insert = dp[i][j + 1] + 1 ;
int delete = dp[i + 1][j] + 1 ;
int min = replace > insert ? insert : replace;
min = delete > min ? min : delete;
dp[i + 1][j + 1] = min;
}
}
}
return dp[len1][len2];
}
It's a DP approach. The problem it since it use a 2D array we cant solve this problem using above method for large strings. Ex: String length > 100000.
So Is there anyway to modify this algorithm to overcome that difficulty ?
NOTE:
The above code will accurately solve the Edit Distance problem for small strings. (which has length below 1000 or near)
As you can see in the code it uses a Java 2D Array "dp[][]" . So we can't initialize a 2D array for large rows and columns.
Ex : If i need to check 2 strings whose lengths are more than 100000
int[][] dp = new int[len1 + 1][len2 + 1];
the above will be
int[][] dp = new int[100000][100000];
So it will give a stackOverflow error.
So the above program only good for small length Strings.
What I'm asking is , Is there any way to solve this problem for large strings(length > 100000) efficiently in java.
First of all, there's no problem in allocating a 100k x 100k int array in Java, you just have to do it in the Heap, not the Stack (and on a machine with around 80GB of memory :))
Secondly, as a (very direct) hint:
Note that in your loop, you are only ever using 2 rows at a time - row i and row i+1. In fact, you calculate row i+1 from row i. Once you get i+1 you don't need to store row i anymore.
This neat trick allows you to store only 2 rows at the same time, bringing down the space complexity from n^2 to n. Since you stated that this is not homework (even though you're a CS undergrad by your profile...), I'll trust you to come up with the code yourself.
Come to think of it I recall having this exact problem when I was doing a class in my CS degree...
I recently took an online test on codility as part of a recruitment process. I was given two simple problems to solve in 1 hour. For those who don't know codility, its an online coding test site where you can solve ACM style problems in many different languages.
If you have 30 or so mins then check this http://codility.com/demo/run/
My weapon of choice is usually Java.
So, one of the problems I have is as follows (I will try to remember, should have taken a screenshot)
Lets say you have array A[0]=1 A[1]=-1 ....A[n]=x
Then what would be the smartest way to find out the number of times when A[i]+A[j] is even where i < j
So if we have {1,2,3,4,5}
we have 1+3 1+5 2+4 3+5 = 4 pairs which are even
The code I wrote was some thing along the lines
int sum=0;
for(int i=0;i<A.length-1;i++){
for (int j=i+1;j<A.length;j++){
if( ((A[i]+A[j])%2) == 0 && i<j) {
sum++;
}
}
}
There was one more restriction that if the number of pairs is greater than 1e9 then it should retrun -1, but lets forget it.
Can you suggest a better solution for this. The number of elements won't exceed 1e9 in normal cases.
I think I got 27 points deducted for the above code (ie it's not perfect). Codility gives out a detailed assessment of what went wrong, I don't have that right now.
The sum of two integers is even if and only if they are either both even or both odd. You can simply go through the array and count evens and odds. The number of possibilities to combine k numbers from a set of size N is N! / ((N - k)! · k!). You just need to put the number of evens/odds as N and 2 as k. For this, the above simplifies to (N · (N - 1)) / 2. All the condition i < j does is to specify that each combination counts only once.
You can find the sum without calculating every pair individually.
A[i]+A[j] is even if A[i] is even and A[j] is even; or A[i] is odd and A[j] is odd.
A running total of odd and even numbers up to j can be kept, and added to sum depending on whether A[j] is odd or even:
int sum = 0;
int odd = 0;
int even = 0;
for(int j = 0; j < A.length; j++) {
if(A[j] % 2 == 0) {
sum += even;
even++;
} else {
sum += odd;
odd++;
}
}
Edit:
If you look at A={1,2,3,4,5}, each value of j would add the number of pairs with A[j] as the second number.
Even values:
A[j]=2 - sum += 0
A[j]=4 - sum += 1 - [2+4]
Odd values:
A[j]=1 - sum += 0
A[j]=3 - sum += 1 - [1+3]
A[j]=5 - sum += 2 - [1+5, 3+5]
Please check this
if (A == null || A.length < 2) {
return 0;
}
int evenNumbersCount = 0;
int oddNumberCount = 0;
for (int aA : A) {
if (aA % 2 == 0) {
evenNumbersCount++;
} else {
oddNumberCount++;
}
}
int i = (evenNumbersCount * (evenNumbersCount - 1)) / 2 + (oddNumberCount * (oddNumberCount - 1)) / 2;
return i > 1000000000 ? -1 : i;
If someone has a problem with understanding what Sante said here is another explanation:
Only odd+odd and even+even gives even. You have to find how many even and odd numbers are there. When you have it imagine that this as a problem with a meeting. How many people distinkt pairs are in the odd numbers list and even numbers list. This is the same problem as how many pairs will say hallo to each other at the party. This is also the number of edges in full graph. The answer is n*(n-1)/2 because there are n people, and you have to shake n-1 peoples hands and divide by 2 because the other person cant count your shake as distinct one. As you have here two separate "parties" going on you have to count them independently.
It's very simple
First you need to find the number of odds and even number in collection.
eg. x is odd if x&1 ==1, even otherwise,
if you have this, knowing that adding two even or two odds to each you get even.
You need to calc the sum of Combinations of two elements from Even numbers and Odd numbers.
having int A[] = {1,2,3,4,5};
int odds=0, evens=0;
for (int i=0; i< A.length; ++i)
{
if (A[i]&1==1) odds++;
else evens++;
}
return odds*(odds-1)/2 + evens*(evens-1)/2;
// Above goes from fact that the number of possibilities to combine k numbers from a set of size N is N! / ((N - k)! · k!). For k=2 this simplifies to (N · (N - 1)) / 2
See this answer also
int returnNumOFOddEvenSum(int [] A){
int sumOdd=0;
int sumEven=0;
if(A.length==0)
return 0;
for(int i=0; i<A.length; i++)
{
if(A[i]%2==0)
sumEven++;
else
sumOdd++;
}
return factSum(sumEven)+factSum(sumOdd);
}
int factSum(int num){
int sum=0;
for(int i=1; i<=num-1; i++)
{
sum+=i;
}
return sum;
}
public int getEvenSumPairs(int[] array){
int even=0;
int odd=0;
int evenSum=0;
for(int j=0; j<array.length; ++j){
if(array[j]%2==0) even++;
else odd++;
}
evenSum=((even*(even-1)/2) + (odd *(odd-1)/2) ;
return evenSum;
}
A Java implementation that works great based on the answer by "Svante":
int getNumSumsOfTwoEven(int[] a) {
long numOdd = 0;
long numEven = 0;
for(int i = 0; i < a.length; i++) {
if(a[i] % 2 == 0) { //even
numOdd++;
} else {
numEven++;
}
}
//N! / ((N - k)! · k!), where N = num. even nums or num odd nums, k = 2
long numSumOfTwoEven = (long)(fact(numOdd) / (fact(numOdd - 2) * 2));
numSumOfTwoEven += (long)(fact(numEven) / (fact(numEven - 2) * 2));
if(numSumOfTwoEven > ((long)1e9)) {
return -1;
}
return numSumOfTwoEven;
}
// This is a recursive function to calculate factorials
long fact(int i) {
if(i == 0) {
return 1;
}
return i * fact(i-1);
}
Algorithms are boring, here is a python solution.
>>> A = range(5)
>>> A
[0, 1, 2, 3, 4]
>>> even = lambda n: n % 2 == 0
>>> [(i, j) for i in A for j in A[i+1:] if even(i+j)]
[(0, 2), (0, 4), (1, 3), (2, 4)]
I will attempt another solution using vim.
You can get rid of the if/else statement and just have the following:
int pair_sum_v2( int A[], int N ) {
int totals[2] = { 0, 0 };
for (int i = 0; i < N; i++ ) {
totals[ A[i] & 0x01 ]++;
}
return ( totals[0] * (totals[0]-1) + totals[1] * (totals[1]-1) ) / 2;
}
Let count odd numbers as n1 and count even numbers as n2.
The sum of Pair(x,y) is even, only if we choose both x and y from the set of even numbers or both x and y from odd set (selecting x from even set and y from odd set or vice-versa will always result in the pair's sum to be an odd number).
So total combination such that each pair's sum is even = n1C2 + n2C2.
= (n1!) / ((n1-2)! * 2!) + (n2!) / ((n2-2)! * 2!)
= (n1 * (n1 - 1)) / 2 + (n2 * (n2 - 1)) / 2
--- Equation 1.
e.g : let the array be like: {1,2,3,4,5}
number of even numbers = n1 = 2
number of odd numbers = n2 = 2
Total pair such that the pair's sum is even from equation: 1 = (2*1)/2 + (3*2)/2 = 4
and the pairs are: (1,3), (1,5), (2,4), (3,5).
Going by traditional approach of adding and then checking might result in an integer overflow in programming on both positive as well as on negative extremes.
This is some pythonic solution
x = [1,3,56,4,3,2,0,6,78,90]
def solution(x):
sumadjacent = [x[i]+x[i+1] for i in range(len(x)-1) if x[i] < x[i+1]]
evenpairslist = [ True for j in sumadjacent if j%2==0]
return evenpairslist
if __name__=="__main__":
result=solution(x)
print(len(result))
int total = 0;
int size = A.length;
for(int i=0; i < size; i++) {
total += (A[size-1] - A[i]) / 2;
}
System.out.println("Total : " + total);