Hi I'm new to this and I don't know how to continue analyzing this algorithm that I have done myself, the conclusion I have right now is:
T(n) ϵ Ω(2n+1)
ϵ O(2n+max)
S(n) ϵ Θ(max)
'max' -> Maximum integer value in the array.
'n' -> Is the input size which is the length of the array.
Is this analysis correct?, 'max' will make it linear? and how can I express this better?
Thanks for the help.
Code
/**
* Method findUnique2
*
* Finds the unique number inside an array of integers
* in which there are always 1 unique number and the rest
* are repeated exactly twice.
*
* NOTE:
* This implementation only works with positive integer numbers.
*
* #param v -> Array with the integer numbers.
* #return The unique number.
*/
public static int findUnique2(int[] v)
{
int max = getMax(v); // Get the maximum number
int[] repetitions = new int[max+1];
boolean found = false;
// +1 to every position
for(int i=0; i<v.length; i++)
repetitions[v[i]]++;
/*
* Finally traversing the array an the position with
* a 1 is the unique number the rest can be either 0
* of not used or 2 which is a repeated number.
*/
int i = -1;
while(!found)
{
i++;
if(repetitions[i] == 1)
found = true;
}
return i;
}
/**
* Method getMax
*
* Traverse an array of integers and returns the maximum
* number stored inside it.
*
* #param v An array of integers
* #return the maximum number among the given array.
*/
public static int getMax(int[] v)
{
int max = v[0];
for(int i=1; i<v.length; i++)
if (max < v[i])
max = v[i];
return max;
}
Related
I'm working on a school assignment and the assignment was to make a heap sorting (In Place) program. Now the program works perfectly fine for arrays with under +- 20 elements, above that it occasionally messes up, however I can't seem to find what's wrong.
/**
* swaps two elements in an array
*
* #param a array
* #param i position of element to swap in a
* #param j position of element to swap in a
*/
public static void swap(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
/**
* restores the heap property in a heap represented as an array
* 4 5 0
* <p>
* restoreHeap([4, 5, 0], 0, 3)
* biggest = 1
*
* #param heap array representation of a heap,
* which might be invalidated
* #param root index of the root of the heap,
* which might be a subtree of the overall heap
* #param range index of the last element in the heap,
* array elements with an index > range are not part of the heap
* <p>
* when the heap property is invalid at root,
* the method fixes the heap first locally before fixing the affected subtree
*/
public static void restoreHeap(int[] heap, int root, int range) {
final int left = root * 2 + 1;
final int right = root * 2 + 2;
final int size = root + range;
int biggest = root;
if (left < size && heap[left] > heap[biggest]) {
biggest = left;
}
if (right < size && heap[right] > heap[biggest]) {
biggest = right;
}
if (biggest != root) {
swap(heap, biggest, root);
restoreHeap(heap, biggest, range - (biggest - root));
}
}
/**
* turns an array of integers into a heap
* <p>
* this is an in-place algorithm, the heap is built in the array itself
* 1 2 4 5 9 3
*
* #param array of integer numbers,
* on return, this array represents a valid heap
*/
public static void buildHeap(int[] array) {
for (int i = 1; i < array.length; i++) {
int temp = i;
while (array[temp / 2] < array[temp]) {
swap(array, temp / 2, temp);
temp /= 2;
}
}
}
/**
* sorts an array of integer numbers
* <p>
* this is an in-place algorithm, the heap is built in the array itself
*
* #param array of elements, on return, this array represents a valid heap
*/
public static void inPlaceHeapSort(int[] array) {
buildHeap(array);
int arrSize = array.length;
while (arrSize > 1) {
swap(array, arrSize - 1, 0);
arrSize--;
restoreHeap(array, 0, arrSize);
}
}
The skeleton for the methods was already there so if you're asking why certain parameters are even there, it's because it was compulsory.
The problem seem's to be indexing, the indexing for left and right seems to be wrong
final int left = root * 2 + 1;
final int right = root * 2 + 2;
here you should change the code to
final int left = root * 2;
final int right = root * 2 + 1;
Also remember that you have to index the array from 1, instead of 0.
This question already has answers here:
Getting permutations of an int[] removing duplicates sets
(5 answers)
Closed 7 years ago.
I want to generate all distinct permutations of array of integers. The array may contain duplicates. but i want to generate all distinct permutations. I have tried next permutation and recursive methods which tend to be very slow. Please suggest.
There are n! different permutations of n elements. Generating a single permutation is cost n (strictly) so the minimum cost of any permutation generation algorithm would be O(n*n!)
Steinhaus–Johnson–Trotter algorithm is one of those algorithms. There are improvements like Shimon Even's and other algorithms like Heap's but none get them under O(n*n!)
Googling "permutation algorithm" gets several different algorithms you can implement, although most use recursion and that means another stack step. Steinhaus–Johnson–Trotter is defined as iterative, so shouldn't get that problem.
Here's a Java implementation
import java.util.Arrays;
import java.util.Iterator;
/**
* this implementation is based in Steinhaus–Johnson–Trotter algorithm and
* Shimon Even's improvement;
*
* #see https
* ://en.wikipedia.org/wiki/Steinhaus%E2%80%93Johnson%E2%80%93Trotter_algorithm
*
*/
public class Permutations implements Iterator<int[]> {
/**
* direction[i] = -1 if the element i has to move to the left, +1 to the
* right, 0 if it does not need to move
*/
private int[] direction;
/**
* inversePermutation[i] is the position of element i in permutation; It's
* called inverse permutation because if p2 is the inverse permutation of
* p1, then p1 is the inverse permutation of p2
*/
private int[] inversePermutation;
/**
* current permutation
*/
private int[] permutation;
/**
* #param numElements
* >= 1
*/
public Permutations(int numElements) {
// initial permutation
permutation = new int[numElements];
for (int i = 0; i < numElements; i++) {
permutation[i] = i;
}
// the support elements
inversePermutation = Arrays.copyOf(permutation, numElements);
direction = new int[numElements];
Arrays.fill(direction, -1);
direction[0] = 0;
}
/**
* Swaps the elements in array at positions i1 and i2
*
* #param array
* #param i1
* #param i2
*/
private static void swap(int[] array, int i1, int i2) {
int temp = array[i1];
array[i1] = array[i2];
array[i2] = temp;
}
/**
* prepares permutation to be the next one to return
*/
private void buildNextPermutation() {
// find the largest element with a nonzero direction, and swaps it in
// the indicated direction
int index = -1;
for (int i = 0; i < direction.length; i++) {
if (direction[permutation[i]] != 0
&& (index < 0 || permutation[index] < permutation[i])) {
index = i;
}
}
if (index < 0) {
// there are no more permutations
permutation = null;
} else {
// element we're moving
int chosenElement = permutation[index];
// direction we're moving
int dir = direction[chosenElement];
// index2 is the new position of chosenElement
int index2 = index + dir;
// we'll swap positions elements permutation[index] and
// permutation[index2] in permutation, to keep inversePermutation we
// have to swap inversePermutation's elements at index
// permutation[index] and permutation[index2]
swap(inversePermutation, permutation[index], permutation[index2]);
swap(permutation, index, index2);
// update directions
if (index2 == 0 || index2 == permutation.length - 1
|| permutation[index2 + dir] > permutation[index2]) {
// direction of chosen element
direction[chosenElement] = 0;
}
// all elements greater that chosenElement set its direction to +1
// if they're before index-1 or -1 if they're after
for (int i = chosenElement + 1; i < direction.length; i++) {
if (inversePermutation[i] > index2) {
direction[i] = -1;
} else {
direction[i] = 1;
}
}
}
}
#Override
public boolean hasNext() {
return permutation != null;
}
#Override
public int[] next() {
int[] result = Arrays.copyOf(permutation, permutation.length);
buildNextPermutation();
return result;
}
}
** Problem statement:
You are given a list of N people who are attending ACM-ICPC World Finals. Each of them are either well versed in a topic or they are not. Find out the maximum number of topics a 2-person team can know. And also find out how many teams can know that maximum number of topics.
Note Suppose a, b, and c are three different people, then (a,b) and (b,c) are counted as two different teams.
Input Format
The first line contains two integers, N and M, separated by a single space, where N represents the number of people, and M represents the number of topics. N lines follow.
Each line contains a binary string of length M. If the ith line's jth character is 1, then the ith person knows the jth topic; otherwise, he doesn't know the topic.
Constraints
2≤N≤500
1≤M≤500
Output Format
On the first line, print the maximum number of topics a 2-person team can know.
On the second line, print the number of 2-person teams that can know the maximum number of topics.
** Problem:
I have 2 errors ("illegal start of expression" and " ';' expected") when I want to declare the 2 numbers maxTopic and numTeam as:
public static int maxTopic = 0;
public static int numTeam = 0;
** Code:
public class Solution {
public static void main(String[] args) {
/* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */
Scanner in = new Scanner(System.in);
int ppl = in.nextInt(); // Number of people
int topic = in.nextInt(); // Number of topics
int A[]; // Array A to store information about topics known by everyone
public static int maxTopic = 0; // Maximum number of topics known
public static int numTeam = 0; // Maximum number of teams that know maxTopic
/* Read the information about topics
and save it to the array A */
for (int i = 0; i < ppl; i++)
A[i] = in.nextInt();
/* Now call the method addCheck() to check each pair of people */
for (int i = 0; i < ppl; i++)
for (int j = i + 1; j < ppl; j++)
Solution.addCheck(A[i], A[j], topic);
System.out.println(maxTopic);
System.out.println(numTeam);
}
/**
* Method used to add up 2 given numbers, check their sum,
* and update the values of maxTopic and numTeam (if possible)
* #param a First number
* #param b Second number
* #param digit Number of digits for a and b
*/
public void addCheck(int a, int b, int digit) {
int sum = a + b; // Calculate the sum of a and b
int numTopic = 0; // Number of topics known for a and b
boolean update = false; // True if the current pair has been used to update numTeam
for (int i = 1; i <= digit; i++) {
if (Solution.getNthDigit(sum, i) != 0)
numTopic++;
if (numTopic > maxTopic)
maxTopic = numTopic;
if ((update == false) && (maxTopic == numTopic)) {
numTeam++;
update = true;
}
}
}
/**
* Get the nth digit of an integer
* #param number The number being considered
* #param n The digit (starting from 1, counted from right to left)
* #return int The value of the nth digit
* Example: getNthDigit(123, 10, 1) produces 3
*/
public int getNthDigit(int number, int n) {
return (int) ((number / Math.pow(10, n - 1)) % 10);
}
}
You can't use public static modifiers within a method. Those are used for class-level declarations only. Since you use the variables in other methods, declare them in the class. Note, your addCheck method should be declared static.
/**
*
* #param d
* currency divisions
* #param p
* target
* #return number of coins
*/
public static int change(int[] d, int p) {
int[] tempArray = new int[p*2]; // tempArray to store set
// of coins forming
// answer
for (int i = 1; i <= p; i++) { // cycling up to the wanted value
int min = Integer.MAX_VALUE; //assigning current minimum number of coints
for (int value : d) {//cycling through possible values
if (value <= i) {
if (1 + tempArray[i - value] < min) { //if current value is less than min
min = 1 + tempArray[1 - value];//assign it
}
}
}
tempArray[i] = min; //assign min value to array of coins
}
return tempArray[p];
}
Can anyone help me see why this is not working please? The method is meant to be given an input of values representing coins, it has an infinite number of these coints with which to form the integer p, the method is to return the minimum number of coins used to get to p.
tempArray is initialized to 0 on all indices.
using tempArray[1-value] is basically giving you 0.
So, all indices from 1 to p has the value 1 + tempArray[1-value]
This is 1. Also, tempArray[1-value] is a negetive index. I think you meant tempArray[i-value]
I have tested that my partitioning algorithm works well, but when it comes time in the implementation to make use of it, I get an array that is not sorted. Since this is for a class, there's a certain I need to write the class itself so that I can return the answer as string. My problem is most likely in the qkSort() method. Here's the code:
private static int splitterElement;
public static void main (String[] args){
System.out.println(myMethod());
}
public static String myMethod() {
String result = "";
int[] testArray = null;
testArray = populateArray(testArray, 7, 10);
result += "Before sort: \n" + printArray(testArray);
testArray = qkSort(testArray,1,testArray.length);
result += "After sort: \n" + printArray(testArray);
return result;
}
//Method to continually call the partition() method
public static int[] qkSort(int[] x, int left, int right){
if (right - left >= 1) {
//after running this method, the global variable splitterElement is assigned.
x = partition(x,left,right);
qkSort(x,left,splitterElement-1);
qkSort(x,splitterElement + 1,right);
}
//base case. if right-left = 0, then the array length is 1,
//and that is already sorted
return x;
}
/**
* Populates an integer array with random integers. Should be used only with
* non-itialized integer arrays.
*
* #param x an uninitialized array of integers and will be returned once it is populated.
* #param sizeOfArray The size that array x will be initialized to.
* #param rangeOfValues The range of values that that each element can be. This value should
* not surpass the maximum value for integers, but no error-checking is performed.
* #return
*/
public static int[] populateArray (int[] x, int sizeOfArray, int rangeOfValues){
x = new int[sizeOfArray];
for (int i = 0; i < sizeOfArray; i++){
x[i] = (int)(Math.random() * rangeOfValues); //place a random number from 0 to rangeOfValues into array.
}
return x;
}
/**
*
* #param x An integer array. It is assumed that x is initialized when the method is called.
* #param left
* #param right The length of the array can be used for the right int.
* #see #populateArray(int[], int, int)
* #return
*/
public static int[] partition (int[] x, int left, int right){
//element of the splitter
int l = (int) (Math.random() * x.length);
splitterElement = l;
x = swap (x,left,l);
//value of the splitter
int t = x[left];
int i = left;
for (int j = left + 1; j < right; j++){
if (x[j] < t){
i++;
x = swap (x,i,j);
}
}
x = swap(x,left,i);
return x;
}
/**
* Places the value at index1 in index2, and places the value at index2 in index1.
*
* #param array The array that will be worked on.
* #param index1 The first place we will switch values.
* #param index2 The second place we will switch values.
* #return
*/
public static int[] swap (int[] array, int index1, int index2){
int temp = array[index1];
array[index1] = array[index2];
array[index2] = temp;
return array;
}
/**
* A simple print method that prints an array.
* #param array Input.
*/
public static String printArray (int[] array){
String result = "";
for (int i = 0; i < array.length; i++){
result += array[i] + " ";
}
result += "\n";
return result;
}
}
Output:
Before sort:
8 9 7 3 4 2 6
After sort:
8 6 3 9 7 2 4
Thanks for any ideas on what my problem is!
I see several issues in your code:
1) the methods don't need to return the array, you could find a better use for the return value
2) using a global variable splitterElement doesn't work because its value can change during the first recursive call to qkSort. Method partition could return its value instead of returning the array, which is useless.
3) the first line of the partition method:
int l = (int) (Math.random() * x.length);
should be:
int l = left + (int) (Math.random() * (right - left));
because youre partitionning the range between left and right, not the whole array.