Sorting an array with heap sort - java

I was working my Algorithm's midterm review and I tried to implement all the pseudo codes by Java in order to have a better understanding of algorithm. But on the heap sort part, there was something wrong with my code. My input array is
{10,16,4,10,14,7,9,3,2,8,1}
and the first element just represents the number of elements that I would like to sort. In other words, the elements needed to be sorted start from index 1.
My output of build max-heap is :
16 14 10 8 7 9 3 2 4 1
And my output of heap sort is :
1 3 2 4 7 8 9 10 14 16
It seemed my build-max-heap part worked well but I couldn't find bugs in heap-sort part, either.
public class Midterm{
public static void main(String[] args){
int[] C = {10,16,4,10,14,7,9,3,2,8,1};
/*for convenience, the first element in array C represent the
number of elements needed to be heapified;
*/
Midterm heap = new Midterm();
int n = C.length - 1;
for (int i = (n / 2); i > 0; i--){
heap.maxHeapify(C, i, n);
}
int index = 1;
while(index <= n){
System.out.print(C[index] + " ");
index++;
}
System.out.println();
Midterm heap2 = new Midterm();
heap2.heapSort(C);
int index2 = 1;
while(index2 <= n){
System.out.print(C[index2] + " ");
index2++;
}
System.out.println();
}
public void heapSort(int[] A){
int n = A.length - 1;
for (int i = n; i >= 2; i--){
exchange(A, 1, i);
maxHeapify(A, 1, i - 1);
}
}
public void maxHeapify(int[] A, int i, int n){
int left = 2 *i, right = 2 * i + 1;
int largest;
if (left < n && A[left] > A[i]){
largest = left;
}else{
largest = i;
}
if (right < n && A[right] > A[largest]){
largest = right;
}
if (largest != i){
exchange(A, i, largest);
maxHeapify(A, largest,n);
}
}
private void exchange(int[] A, int i , int j){
int temp = A[i];
A[i] = A[j];
A[j] = temp;
}
}

There are 2 mistakes in your code:
1. The for loop for the heapsort goes from last element to first element, so
for (int i = n; i >= 2; i--){
should be:
for (int i = n; i >= 1; i--){
because the indices start from 0.
2. After performing a exchange(A, 1, i), the right call should be:
maxHeapify(A, 1, i)

check the below code.
public class HeapSort
{
public void sort(int arr[])
{
int n = arr.length;
// Build heap (rearrange array)
for (int i = n / 2 - 1; i >= 0; i--)
heapify(arr, n, i);
// One by one extract an element from heap
for (int i=n-1; i>=0; i--)
{
// Move current root to end
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
// call max heapify on the reduced heap
heapify(arr, i, 0);
}
}
// To heapify a subtree rooted with node i which is
// an index in arr[]. n is size of heap
void heapify(int arr[], int n, int i)
{
int largest = i; // Initialize largest as root
int l = 2*i + 1; // left = 2*i + 1
int r = 2*i + 2; // right = 2*i + 2
// If left child is larger than root
if (l < n && arr[l] > arr[largest])
largest = l;
// If right child is larger than largest so far
if (r < n && arr[r] > arr[largest])
largest = r;
// If largest is not root
if (largest != i)
{
int swap = arr[i];
arr[i] = arr[largest];
arr[largest] = swap;
// Recursively heapify the affected sub-tree
heapify(arr, n, largest);
}
}
/* A utility function to print array of size n */
static void printArray(int arr[])
{
int n = arr.length;
for (int i=0; i<n; ++i)
System.out.print(arr[i]+" ");
System.out.println();
}
// Driver program
public static void main(String args[])
{
int arr[] = {12, 11, 13, 5, 6, 7};
int n = arr.length;
HeapSort ob = new HeapSort();
ob.sort(arr);
System.out.println("Sorted array is");
printArray(arr);
}
}

Related

Java Bubble Sort Returns Only Partially Sorted

I'm new to Java, so have been trying to translate some old JS exercises into Java.
Here's a bubble sort (I know, I know...) that's not working:
class BubbleSort{
public static void main(String args[]){
int nums [] = {5, 4, 6, 3, 12, 1};
Boolean swap = true;
while(swap){
swap = false;
for(int i = 1; i<nums.length ; i++){
if (nums[i - 1] > nums[i]){
int t = nums[i-1];
nums[i-1] = nums[i];
nums[i] = t;
swap = true;
}else{
swap = false;
}
}
}
System.out.print("Sorted: ");
for(int j=0 ; j<nums.length ; j++)
System.out.print(nums[j] + " ");
}
}
It returns 4, 3, 5, 1, 6, 12...
So a few swaps are taking place, but something is making it end early.
Can anyone spot my issue?
Just remove the else block in your code (as in the code sample below).
You have to make another swap as soon as one thing is not ordered.
In your code, you only make another swap if the last items are in the wrong order. If the end of your array is ordered too soon, your sort ends too soon too.
class BubbleSort{
public static void main(String args[]){
int nums [] = {5, 4, 6, 3, 12, 1};
Boolean swap = true;
while(swap){
swap = false;
for(int i = 1; i<nums.length ; i++){
if (nums[i - 1] > nums[i]){
int t = nums[i-1];
nums[i-1] = nums[i];
nums[i] = t;
swap = true;
}/* else{
swap = false;
}*/
}
}
System.out.print("Sorted: ");
for(int j=0 ; j<nums.length ; j++)
System.out.print(nums[j] + " ");
}
}
When your first inner loop ends without a swap, that swap marker boolean is false, and the outer loop stops.
That is all there is to this.
remove the else block and it will work
Boolean swap = true;
while(swap){
swap = false;
for(int i = 1; i<nums.length ; i++){
if (nums[i - 1] > nums[i]){
int t = nums[i-1];
nums[i-1] = nums[i];
nums[i] = t;
swap = true;
}
}
}
this else block make it wrong because if your last check in for dont need swap, it will end the outer while loop
static void sort(int[] a) {
for (int i = a.length - 2; i >= 0; i--) {
boolean flag = true;
for (int j = 0; j <= i; j++) {
if (a[j] > a[j + 1]) {
flag = false;
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
if (flag)
break;
}
}
As many others have already said, setting swap to false in your comparison step is incorrect. Your code will terminate prematurely if the final comparison in the loop does not result in a swap.
Since you are asking about bubbleSort, what you have implemented is not actually bubble sort. classic BubbleSort uses a pair of nested for loops. The outer loop finds the largest number in the list and ensures it bubbles up to the top position in the array starting at index n-1, then n-2, etc.
The inner loop scans all elements from index 0 to up to that position set by the outer loop, and pairwise compares the elements, and swaps them if they are out of order.
Here is classic bubbleSort:
class BubbleSort{
/**
* Swaps to elements in array data at index1 and index2
*
* #param data the array whose elements should be swapped
* #param index1 index of first element to be swapped
* #param index2 index of second elememt to be swapped with the first
*
*/
private static <T extends Comparable<T>> void swap(T[] data, int index1, int index2)
{
T temp = data[index1];
data[index1] = data[index2];
data[index2] = temp;
}
/**
* Sorts the specified array of objects using a bubble sort algorithm.
*
* #param data the array to be sorted
*/
public static <T extends Comparable<T>> void bubbleSort(T[] data)
{
int position, scan;
for (position = data.length - 1; position >= 0; position--)
{
for (scan = 0; scan <= position - 1; scan++)
{
if (data[scan].compareTo(data[scan+1]) > 0)
swap(data, scan, scan + 1);
}
}
}
public static void main(String args[]){
Integer nums [] = {5, 4, 6, 3, 12, 1};
bubbleSort(nums);
System.out.print("Sorted: ");
for(int j=0 ; j<nums.length ; j++)
System.out.print(nums[j] + " ");
System.out.println("");
}
}
Yes. Don't reset swap to false with the else; and prefer boolean to Boolean. Like,
boolean swap = true;
while (swap) {
swap = false;
for (int i = 1; i < nums.length; i++) {
if (nums[i - 1] > nums[i]) {
int t = nums[i - 1];
nums[i - 1] = nums[i];
nums[i] = t;
swap = true;
}
}
}
Outputs
Sorted: 1 3 4 5 6 12
With no other changes. This could be refined with a few lambdas and extracting the swap method would also help. Something like,
private static void swap(int[] arr, int i, int j) {
if (arr[i] > arr[j]) {
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
}
public static void main(String args[]) {
int nums[] = { 5, 4, 6, 3, 12, 1 };
IntPredicate ip = i -> nums[i - 1] > nums[i];
while (IntStream.range(1, nums.length).anyMatch(ip)) {
IntStream.range(1, nums.length).forEach(i -> swap(nums, i - 1, i));
}
System.out.print("Sorted: " + IntStream.of(nums)
.mapToObj(String::valueOf).collect(Collectors.joining(" ")));
}

Shift array to the left

so I'm trying to shift an array to the left, eg, if the original array was '1,2,3,4', the transformed one would become '2,3,4,1', this is what i have so far and i keep getting an missing return statement error, how would i go about fixing it?
public int shift ( int [] d){
for(int from =1; from <= d.length-1; from++)
d[from-1]= d[from];
System.out.println ("d[from]"+",d[0]");
}
Your logic is right but you just need some modify in your code.
int data[]={1,2,3,4};
shift(data);
//print out Shifted Array
for(int n : data){
System.out.println(n);
}
public void shift(int[] d){
int f=d[0]; // Store first index
int from=1;
for(;from<d.length;from++){
d[from-1]=d[from];
}
d[from-1]=f; //set first index to the last index
}
You don't need to return any data because java pass the reference of
the object not value.
public static void shift(int[] arr, int offs) {
// e.g. arr = 1,2,3,4,5,6,7,8,9; offs = 3
offs %= arr.length;
offs = offs < 0 ? arr.length + offs : offs;
if (offs > 0) {
// reverse whole array (arr = 9,8,7,6,5,4,3,2,1)
for (int i = 0, j = arr.length - 1; i < j; i++, j--)
swap(arr, i, j);
// reverse left part (arr = 7,8,9,6,5,4,3,2,1)
for (int i = 0, j = offs - 1; i < j; i++, j--)
swap(arr, i, j);
// reverse right part (arr = 7,8,9,1,2,3,4,5,6)
for (int i = offs, j = arr.length - 1; i < j; i++, j--)
swap(arr, i, j);
}
}
private static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
Using Collections.rotate:
public List<Integer> shift(int [] d) {
List<Integer> intList = new ArrayList<Integer>();
for (int index = 0; index < d.length; index++) {
intList.add(d[index]);
}
Collections.rotate(intList, -1);
return intList;
}
The following code is in PHP to shift the array to left based on the given transformation number.
<?php
$a = [2,3,4,5,6];
$k1 = 2;
$k2 = 10;
function leftshift($ar, $n , $k){
$mod = $k % $n;
for ($i = 0; $i < $n; $i++) {
echo ($ar[($mod + $i) % $n]) , " ";
echo "\n";
}
}
$n = count($a);
leftshift($a,$n,$k1);
leftshift($a,$n,$k2);
?>
public int shift (int[] d) {
for(int from =1; from <= d.length-1; from++)
d[from-1]= d[from];
System.out.println ("d[from]"+",d[0]");
return d.length=0?0:d[0];
}
Note that an array maybe of size zero, and you may get "index out of bounds exception".

Find longest subarray whose sum divisible by 3 with O(N) Complexity

i have big question here , if you can see below the code you will see code with O(N) complexity. im only try to decrease it to O(N^2),
Im treid to do it with O(N) but without any secces .
private static int f (int[]a, int low, int high)
{
int res = 0;
for (int i=low; i<=high; i++)
res += a[i];
return res;
}
public static int what (int []a)
{
int temp = 0;
for (int i=0; i<a.length; i++)
{
for (int j=i; j<a.length; j++)
{
int c = f(a, i, j);
if (c%3 == 0)
{
if (j-i+1 > temp)
temp = j-i+1;
}
}
}
return temp;
}
couple of exemple :
int[] a={1,2,4,1}; output : 2 ==> if you can see (1+2= 3 ) ,(2+4=6) so those is %3=0 ==> beacuse that the number is 2 beacuse is two subarray that giving me %3 to be =0.
int[] a={3,4,4,2}; output : 2
int[] a={3,3,3,3,0,1}; output : 5
int[] a={3,2,7,6,6,1}; output : 5

How to rotate an array?

I have the following problem to test:
Rotate an array of n elements to the right by k steps.
For instance, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to
[5,6,7,1,2,3,4]. How many different ways do you know to solve this problem?
My solution in intermediate array:
With Space is O(n) and time is O(n), I can create a new array and then copy elements to the new array. Then change the original array by using System.arraycopy().
public void rotate(int[] nums, int k) {
if (k > nums.length)
k = k % nums.length;
int[] result = new int[nums.length];
for (int i = 0; i < k; i++) {
result[i] = nums[nums.length - k + i];
}
int j = 0;
for (int i = k; i < nums.length; i++) {
result[i] = nums[j];
j++;
}
System.arraycopy(result, 0, nums, 0, nums.length);
}
But is there a better way we can do it with bubble rotate (like bubble sort) in O(1) space?
Method 1 - The Reversal Algorithm(Good One):
Algorithm:
rotate(arr[], d, n)
reverse(arr[], l, n);
reverse(arr[], 1, n-d) ;
reverse(arr[], n - d + 1, n);
Let AB are the two parts of the input array where A = arr[0..n-d-1] and B = arr[n-d..n-1]. The idea of the algorithm is:
Reverse all to get (AB) r = BrAr.
Reverse A to get BrA. /* Ar is reverse of A */
Reverse B to get BA. /* Br is reverse of B */
For arr[] = [1, 2, 3, 4, 5, 6, 7], d =2 and n = 7
A = [1, 2, 3, 4, 5] and B = [ 6, 7]
Reverse all, we get BrAr = [7, 6, 5, 4, 3, 2, 1]
Reverse A, we get ArB = [7, 6, 1, 2, 3, 4, 5]
Reverse B, we get ArBr = [6, 7, 5, 4, 3, 1, 2]
Here is the Code Snippet:
void righttRotate(int arr[], int d, int n)
{
reverseArray(arr, 0, n-1);
reverseArray(arr, 0, n-d-1);
reverseArray(arr, n-d, n-1);
}
void reverseArray(int arr[], int start, int end)
{
int i;
int temp;
while(start < end)
{
temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
}
Method 2 - A Juggling Algorithm
Divide the array in different sets where number of sets is equal to GCD of n and d and move the elements within sets.
If GCD is 1, then elements will be moved within one set only, we just start with temp = arr[0] and keep moving arr[I+d] to arr[I] and finally store temp at the right place.
Here is an example for n =12 and d = 3. GCD is 3 and
Let arr[] be {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
Elements are first moved in first set
arr[] after this step --> {4 2 3 7 5 6 10 8 9 1 11 12}
Then in second set.
arr[] after this step --> {4 5 3 7 8 6 10 11 9 1 2 12}
Finally in third set.
arr[] after this step --> {4 5 6 7 8 9 10 11 12 1 2 3}
Here is the code:
void leftRotate(int arr[], int d, int n)
{
int i, j, k, temp;
int gcd = gcd(d, n);
for (i = 0; i < gcd; i++)
{
/* move i-th values of blocks */
temp = arr[i];
j = i;
while(1)
{
k = j + d;
if (k >= n)
k = k - n;
if (k == i)
break;
arr[j] = arr[k];
j = k;
}
arr[j] = temp;
}
}
int gcd(int a,int b)
{
if(b==0)
return a;
else
return gcd(b, a%b);
}
Time complexity: O(n)
Auxiliary Space: O(1)
Method 3 - Rotate one by one:
righttRotate(arr[], d, n)
start
For i = 0 to i < d
Right rotate all elements of arr[] by one
end
To rotate by one, store arr[n-1] in a temporary variable temp, move arr[1] to arr[2], arr[2] to arr[3] …and finally temp to arr[0]
Let us take the same example arr[] = [1, 2, 3, 4, 5, 6, 7], d = 2, rotate arr[] by one 2 times. We get [7, 1, 2, 3, 4, 5, 6] after first rotation and [ 6, 7, 1, 2, 3, 4, 5] after second rotation.
Her is Code Snippet:
void leftRotate(int arr[], int d, int n)
{
int i;
for (i = 0; i < d; i++)
leftRotatebyOne(arr, n);
}
void leftRotatebyOne(int arr[], int n)
{
int i, temp;
temp = arr[n-n];
for (i = 0; i < n-1; i++)
arr[i] = arr[i+1];
arr[n - 1] = temp;
}
Time complexity: O(n*d)
Auxiliary Space: O(1)
The following code will do your job. This is for right rotate.
public void rightrotate(int[] nums, int k) {
k %= nums.length;
reverse(nums, 0, nums.length - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, nums.length - 1);
}
public void reverse(int[] nums, int start, int end) {
while (start < end) {
int temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
start++;
end--;
}
}
If you want to do left rotate just use the following
public void leftrotate(int[] nums, int k) {
k %= nums.length;
reverse(nums, 0, k - 1);
reverse(nums, k, nums.length - 1);
reverse(nums, 0, nums.length - 1);
}
When k is negative, it rotates to the left.
Space is O(1) and time is O(n)
static void rotate(int[] num, int k) {
int n = num.length;
k = k % n;
if (k < 0) k += n;
int[] result = new int[n];
System.arraycopy(num, 0, result, k, n - k);
System.arraycopy(num, n - k, result, 0, k);
System.arraycopy(result, 0, num, 0, n);
}
ArrayUtil class is used to provide following utilities in primitive array
swap array elements
reverse array between startIndex and endIndex
leftRotate array by shift
Algorithm for array rotation by shift-
If we have to reverse array by shift value then take mod(%) with array length so that shift will become smaller than array length.
Reverse array between index 0 and shift-1
Reverse array between index shift and length-1.
Reverse complete array between index 0 and length-1.
Space Complexity: In-place Algorithm, No extra space needed so O(1).
Time Complexity : Array reversal of size k take O(k/2) i.e swapping k/2 pairs of elements.
Array Reversal time- O(k) for k size array.
Total time in Rotation-
O(1) ..........for step 1
O(shift) ......for step 2
O(n - shift) ...for step 3
O(n) ...........for step 4
Total Time for array Rotation: O(1) + O(shift) + O(n-shift) + O(n) = O(n)
public class Solution {
public static void main(String[] args) {
int k = 3;
int a[] = {1,2,3,4,5,6,7};
ArrayUtil.leftRotate(a, k);
for (int i : a)
System.out.println(i);
}
}
class ArrayUtil {
public static final boolean checkIndexOutOfRange(int[] array, int index) {
if (index < 0 || index > array.length)
return true;
return false;
}
public static final void swap(int[] array, int i, int j) {
if (checkIndexOutOfRange(array, i) || checkIndexOutOfRange(array, j))
return;
int t = array[i];
array[i] = array[j];
array[j] = t;
}
public static final void reverse(int[] array, int startIndex, int endIndex) {
if (checkIndexOutOfRange(array, startIndex) || checkIndexOutOfRange(array, endIndex))
return;
while (startIndex < endIndex) {
swap(array, startIndex, endIndex);
startIndex++;
endIndex--;
}
}
public static final void reverse(int[] array) {
reverse(array, 0, array.length - 1);
}
public static final void leftRotate(int[] array, int shift) {
int arrayLength = array.length;
if (shift >= arrayLength)
shift %= arrayLength;
reverse(array, 0, shift - 1);
reverse(array, shift, arrayLength - 1);
reverse(array);
}
}
Partial Code for ONE time array rotation
last=number_holder[n-1];
first=number_holder[0];
//rotation
number_holder[0]=last;
for(i=1;i<n;i++)
{
last=number_holder[i];
number_holder[i]=first;
first=last;
}
Display the array
for(i=1;i<n;i++)
{
System.out.println(number_holder[i]);
}
AFAIK, there are three ways to rotate an array with O(1) extra space, or put it another way, to swap two contiguous subarray.
reverse approach. reverse both part, then reverse all. most easy to code.
successively swap two contiguous block, until all items are in place.
juggling rotate, shell sort like. -- worse cache performance.
C++ has builtin function std::rotate(), which takes three iterator first, middle, last,
and return new_middle, which is where the old first element lies in the rotated
sequence.
I have checked the implementation on my computer, which use second approach I listed above.
(line 1246 in /usr/lib/gcc/i686-pc-cygwin/5.4.0/include/c++/bits/stl_algo.h).
Below is my implementation of rotate, with test program.
#include <iostream>
#include <vector>
// same logic with STL implementation, but simpler, since no return value needed.
template <typename Iterator>
void rotate_by_gcd_like_swap(Iterator first, Iterator mid, Iterator last) {
if (first == mid) return;
Iterator old = mid;
for (; mid != last;) {
std::iter_swap(first, mid);
++first, ++mid;
if (first == old) old = mid; // left half exhausted
else if (mid == last) mid = old;
}
}
// same logic with STL implementation
template <typename Iterator>
Iterator rotate_by_gcd_like_swap_then_return_new_mid(Iterator first, Iterator mid, Iterator last) {
if (first == mid) return last;
if (mid == last) return first;
Iterator old = mid;
for(;;) {
std::iter_swap(first, mid);
++first, ++mid;
if (first == old) old = mid;
if (mid == last) break;
}
Iterator result = first; // when first time `mid == last`, the position of `first` is the new `mid`.
for (mid = old; mid != last;) {
std::iter_swap(first, mid);
++first, ++mid;
if (first == old) old = mid;
else if (mid == last) mid = old;
}
return result;
}
int main() {
using std::cout;
std::vector<int> v {0,1,2,3,4,5,6,7,8,9};
cout << "before rotate: ";
for (auto x: v) cout << x << ' '; cout << '\n';
int k = 7;
rotate_by_gcd_like_swap(v.begin(), v.begin() + k, v.end());
cout << " after rotate: ";
for (auto x: v) cout << x << ' '; cout << '\n';
cout << "sz = " << v.size() << ", k = " << k << '\n';
}
Above solutions talk about shifting array elements either by reversing them or any other alternative.
I've unique solution. How about determining the starting position of element after n rotations. Once we know that, then simply insert elements from that index and increment counter using modulus operation. Using this method we can avoid using extra array operations and so on.
Here is my code:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
void rotateLeft(int n,int r) {
vector<long int> vec(n);
int j = n;
// get the position of starting index after r left rotations.
while(r!=0) {
--j;
if(j==0)
j = n;
--r;
}
for(long int i=0;i<n;++i) {
// simply read the input from there and increment j using modulus operator.
cin>>vec[j];
j = (j+1)%n;
}
// print the array
for(long int i=0;i<n;++i)
cout<<vec[i]<<" ";
}
int rotateRight (int n,int r) {
// get the position of starting index after r left rotations.
int j = r % n;
vector<long int> vec(n);
for(int i=0;i<n;i++) {
cin>>vec[j];
j=(j+1)%n;
}
for(int i=0;i<n;i++)
cout<<vec[i]<<" ";
}
int main() {
long int n,r; // n stands from number of elements in array and r stands for rotations.
cin>>n>>r;
// Time Complexity: O(n+r) Space Complexity: O(1)
rotateLeft(n,r);
// Time Complexity: O(n) Space Complexity: O(1)
rotateRight(n,r);
return 0;
}
Python code:
def reverse(arr,start , end):
while(start <= end):
arr[start] , arr[end] = arr[end] , arr[start]
start = start+1
end = end-1
arr = [1,2,3,4,5,6,7]
n = 7
k = 2
reverse(arr,0,n-1)
# [7,6,5,4,3,2,1]
reverse(arr,0,n-1-k)
# [3,4,5,6,7,2,1]
reverse(arr,n-k,n-1)
# [3,4,5,6,7,1,2]
print arr
# [3, 4, 5, 6, 7, 8, 9, 1, 2]
In Ruby Its very simple, Please take a look, Its one line.
def array_rotate(arr)
i, j = arr.length - 1, 0
arr[j],arr[i], i, j = arr[i], arr[j], i - 1, j + 1 while(j<arr.length/2)
puts "#{arr}"
end
Input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
Output: [20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
1.using a temp array and O(n) time
public static void rotateAnArrayUsingTemp(int arr[], int d, int n) {
int temp[] = new int[d];
int tempIndex = 0;
for (int i = 0; i < d; i++) {
temp[i] = arr[i];
}
for (int i = 0; i < arr.length - d; i++) {
arr[i] = arr[i + d];
}
for (int i = arr.length - d; i < arr.length; i++) {
arr[i] = temp[tempIndex++];
}
}
This is a simple solution to rotate an array.
public class ArrayRotate {
public int[] rotateArray(int array[], int k) {
int newArray[] = new int[array.length];
for (int i = 0; i < array.length; i++) {
newArray[(i + k) % array.length] = array[i];
}
System.arraycopy(newArray, 0, array, 0, array.length);
return newArray;
}
public static void main(String[] args) {
int array[] = { 1, 2, 3, 4, 5, 6, 7 };
ArrayRotate rotate = new ArrayRotate();
rotate.display(rotate.rotateArray(array, 3));
}
public void display(int array[]) {
for (int i : array) {
System.out.print(i + ",");
}
}
}
Runtime complexity is O(n)
There are several other algorithm to achieve the same.
using temp array
Rotate One By one
Juggling algorithm
reversal method
This solution is O(1) space and O(N) time. It is in C#, takes an array parameter and rotates it in place. The algorithm goes through the first s (the shift) elements, starting with the first element moves it to the s_th position, then moves the s_th to the 2s_th position etc. If each of the first s elements rotates back to itself then there will be (arrayLength / s) * s = arrayLength loops, and at the end the array will be rotated by s. If the first s elements do not rotate back themselves, then there will still be cycles, say if s = 4, there could be one cycle which is 1-3-1 and the second 2-4-2, the line - if (ind == indAtBeg), checks for a cycle and terminates the while loop. The variable loopCount increments, when there is a rotation starting at any of the first s elements.
public static void rotateArrayByS(int[] ar, int s)
{
int len = ar.Length, ind = 0, temp1 = ar[0],
temp2 /*temp1 and temp2 for switching elements*/,
loopCount /*rotations starting at the first s elemtns of ar*/ = 0;
s %= len;
while (loopCount < s)
{
int indAtBeg = ind;
temp1 = ar[ind];
bool done = false;
while (!done)
{
if (ind < s)
loopCount++;
ind = (ind + s) % len;
//cycle detected
if (ind == indAtBeg)
done = true;
//switch the elements
temp2 = ar[ind];
ar[ind] = temp1;
temp1 = temp2;
}
++ind;
}
}
#include <stdio.h>
int
main(void)
{
int arr[7] = {1,2,3,4,5,6,7};
int new_arr[7] = {0};
int k = 3;
int len = 7;
int i=0;
for (i = (len-1); i>=0; i--) {
if ((i+k) >= len) {
new_arr[(i+k-len)] = arr[i];
} else {
new_arr[(i+k)] = arr[i];
}
}
for (i=0;i<len;i++) {
printf("%d ", new_arr[i]);
}
return 0;
}
Time complexity O(n)
Space complexity O(2*n).
Thanks.
Here is the complete Java code for left and right array rotation by k steps
import java.util.*;
public class ArrayRotation {
private static Scanner sc;
public static void main(String[] args) {
int n,k;
sc = new Scanner(System.in);
System.out.print("Enter the size of array: ");
n = sc.nextInt();
int[] a = new int[n];
System.out.print("Enter the "+n+" elements in the list: ");
for(int i=0;i<n;i++)
a[i] = sc.nextInt();
System.out.print("Enter the number of left shifts to array: ");
k = sc.nextInt();
System.out.print("Array before "+k+" shifts: ");
display(a);
leftRoation(a,k);
System.out.println();
System.out.print("Array after "+k+" left shifts: ");
display(a);
rightRoation(a,k);
System.out.println();
System.out.print("Array after "+k+" right shifts: ");
display(a);
}
public static void leftRoation(int[] a, int k){
int temp=0, j;
for(int i=0;i<k;i++){
temp = a[0];
// j=0; // both codes work i.e. for loop and while loop as well
// while(j<a.length-1){
// a[j]=a[j+1];
// j++;
// }
for(j=0;j<a.length-1;j++)
a[j]=a[j+1];
a[j]=temp;
}
}
public static void rightRoation(int[] a, int k){
int temp=0, j;
for(int i=0;i<k;i++){
temp = a[a.length-1];
for(j=a.length-1;j>0;j--)
a[j]=a[j-1];
a[j]=temp;
}
}
public static void display(int[] a){
for(int i=0;i<a.length;i++)
System.out.print(a[i]+" ");
}
}
/****************** Output ********************
Enter the size of array: 5
Enter the 5 elements in the list: 1 2 3 4 5
Enter the number of left and right shifts to array: 2
Array before 2 shifts: 1 2 3 4 5
Array after 2 left shifts: 3 4 5 1 2
Array after 2 right shifts: 1 2 3 4 5 // here the left shifted array is taken as input and hence after right shift it looks same as original array.
**********************************************/
My solution... (a: the array, n : size of array, k: number of shifts) :
public static int[] arrayLeftRotation(int[] a, int n, int k) {
if (k == 0) return a;
for (int i = 0; i < k; i++) {
int retenue = a[0];
int[] copie = java.util.Arrays.copyOfRange(a, 1, n );
for (int y = 0; y <= copie.length - 1 ; y++) {
a[y] = copie[y];
}
a[n-1] = retenue;
}
return a;
}
Java implementation for right rotation
public int[] solution(int[] A, int K) {
int len = A.length;
//Create an empty array with same length as A
int arr[] = new int[len];
for (int i = 0; i < len; i++) {
int nextIndex = i + K;
if (nextIndex >= len) {
// wraps the nextIndex by same number of K steps
nextIndex = nextIndex % len;
}
arr[nextIndex] = A[i];
}
return arr;
}
>>> k = 3
>>> arr = [1,2,3,4,5,6,7]
>>> actual_rot = k % len(arr)
>>> left_ar = arr[:-actual_rot]
>>> right_ar = arr[-actual_rot:]
>>> result = right_ar + left_ar
>>> result
[5, 6, 7, 1, 2, 3, 4]
A better way to rotate an array by k steps is:
a = [1,2,3,4,5,6]
b = a[:]
k = 2
for i in range(len(a)):
a[(i + k) % len(a)] = b[i]## (rotate right by k steps)
#a[(i - k) % len(a)] = b[i]## (rotate left by k steps)
print(a)
o/p:
[6, 5, 1, 2, 3, 4]
how to rotate an array, IN this function first argument - array, the second argument is
a number or integer.
def rotLeft(a, d):
data = a
n = d
get = data[n:len(data)]
remains = data[0:n]
data.clear()
for i in get:
data.append(i)
for x in remains:
data.append(x)
return data
This is rotating the array to the right by k steps, where k is non-negative
for (int i = 0; i < k; i++) {
for (int j = nums.length - 1; j > 0; j--) {
int temp = nums[j];
nums[j] = nums[j - 1];
nums[j - 1] = temp;
}
}
return nums;
if (k > arr.length) {
k = k % arr.length;
}
int n = arr.length - k;
int count = 0;
outer:
for (int i = arr.length - 1; i >= n; i--) {
int temp = arr[i];
inner:
for (int j = i - 1; j >= 0; j--) {
arr[j + 1] = arr[j];
if (j == 0) {
int temp2 = arr[j];
arr[j] = temp;
i = arr.length;
count++;
if (count == k) {
break outer;
}
}
}
}
Here I have solved the same problem in go.
Try to run in go playground...
sample code.
func rotate(a []int, k int) {
for j := 0; j < k ; j++ {
temp := a[len(a)-1]
for i := len(a) - 1; i > 0; i-- {
a[i] = a[i-1]
}
a[0] = temp
}
}
If you are looking for the soltuion of Codility - Cyclic Rotation Problem then, here is the JavaScript code which gave 100% for me.
function solution(A, K) {
const L = A.length - (K % A.length); // to get the rotation length value below array length (since rotation of product of array length gives same array)
const A1 = A.slice(L); // last part of array which need to be get to front after L times rotation
const A2 = A.slice(0, L); // part which rotate L times to right side
const Result = [...A1, ...A2]; // reverse and join both array by spreading
return Result;
}
Rotate an array of n elements to the right by k steps.
For instance, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to [5,6,7,1,2,3,4].
In JS the solution will be 2 part, in two line:
function rotateArray(array,k){
// remove the rotation part
const splice = [...array].splice(0,k); //... for make a clone;
// add reversed version of the what left
return array.concat(splice.reverse()) from original array.
}

How can we rotate an array to the left?

EX: I have an array {1, 2, 3, 4, 5} and an integer number 7
It will rotate 7 spaces to the right like: {4, 5, 1, 2, 3}
I also have that array {1, 2, 3, 4, 5} and an integer number -7
It will rotate 7 spaces to the left like: {3, 4, 5, 1, 2}
I have rotated the array to the right by using:
for(int i = 0; i < data.length; i++){
result[(i+n) % data.length ] = data[i];
}
But how can we rotate an array to the left?
Rotating to the left by n is the same as rotating to the right by length-n.
Rotate right (for positive n):
for(int i = 0; i < data.length; i++){
result[(i+n) % data.length ] = data[i];
}
Rotate left (for positive n):
for(int i = 0; i < data.length; i++){
result[(i+(data.length-n)) % data.length ] = data[i];
}
This way you can avoid a modulo of a negative number.
If you want to input an integer n that rotates right if n is positive and left if n is negative, you can do it like this:
int[] rotateArray(int n, int[] data)
{
if(n < 0) // rotating left?
{
n = -n % data.length; // convert to +ve number specifying how
// many positions left to rotate & mod
n = data.length - n; // rotate left by n = rotate right by length - n
}
int[] result = new int[data.length];
for(int i = 0; i < data.length; i++){
result[(i+n) % data.length ] = data[i];
}
return result;
}
In case rotate to the left, you can use this to avoid a modulo of a negative number:
int[] data = {1, 2, 3, 4, 5};
int[] result = new int[data.length];
for (int i = 0; i < data.length; i++) {
result[(i + (data.length - 2)) % data.length] = data[i];
}
for (int i : result) {
System.out.println(i);
}
You may also use linkedlist to achieve the same.
Integer[] arr = {1,2,3,4,5};
LinkedList<Integer> ns = new LinkedList<Integer>(Arrays.asList(arr));
int rotate=3;
if(rotate<0)
rotate += arr.length;
List<Integer> leftlist = ns.subList(0, rotate);
List<Integer> rightlist = ns.subList(rotate, arr.length);
LinkedList<Integer> result = new LinkedList<Integer>();
result.addAll(rightlist);
result.addAll(leftlist);
System.out.println(result);
If you want to rotate an array named a[n] with n as the size of an array and d as the number of rotation (in your case d=7), you can use this code:
d = d % n;
for(int i=d;i<n;i++){
System.out.print(a[i]+" ");
}
for(int i=0;i<(d);i++){
System.out.print(a[i]+" ");
}
This code will print the array elements in order after the left rotation is performed. If you want you can store it in another array, or you can show array elements as shown in the above method.
Here is the complete java program for n left rotations of an array.
public class ArrayRotation {
private static Scanner sc;
public static void main(String[] args) {
int n,k;
sc = new Scanner(System.in);
System.out.print("Enter the size of array: ");
n = sc.nextInt();
int[] a = new int[n];
System.out.print("Enter the "+n+" elements in the list: ");
for(int i=0;i<n;i++)
a[i] = sc.nextInt();
System.out.print("Enter the number of left shifts to array: ");
k = sc.nextInt();
System.out.print("Array before "+k+" shifts: ");
display(a);
solution(a,k);
System.out.println();
System.out.print("Array after "+k+" shifts: ");
display(a);
}
public static void solution(int[] a, int k){
int temp=0, j;
for(int i=0;i<k;i++){
temp = a[0];
// j=0; // both codes work i.e. for loop and while loop as well
// while(j<a.length-1){
// a[j]=a[j+1];
// j++;
// }
for(j=0;j<a.length-1;j++)
a[j]=a[j+1];
a[j]=temp;
}
}
public static void display(int[] a){
for(int i=0;i<a.length;i++)
System.out.print(a[i]+" ");
}
}
public static int[] arrayLeftRotation(int[] array, int elements, int rotations) {
// i = checks number of rotations
for (int i = 0; i < rotations; i++) {
int first = array[0];
int last = array[elements - 1];
// j = rotates each element
for (int j = 0; j < elements; j++) {
// check if at first index
if (j == 0) {
array[elements - 1] = first;
}
// check if at last index
if (j == (elements - 1)) {
// if at last index: make element in index before last = to last element
array[elements - 2] = last;
} else {
array[j] = array[j + 1];
}
}
}
return array;
}
This is the cleanest answer I could come up with.
Notice that you need to compute rotations % length so that your program is robust to a number of rotations greater than the size of your array.
static int[] rotateLeft(int[] arr, int rotations) {
int length = arr.length;
int[] result = new int[length];
rotations = rotations % length; // robust to rotations > length
int position = length - rotations; // compute outside the loop to increase performance
for (int i = 0; i < length; i++) {
result[(position + i) % length] = arr[i];
}
return result;
}
I used the below approach putting the array into a new array in its new position.
int length = a.length;
int[] newArr = new int[a.length];
for (int i = length - 1; i >= 0 ; i--){
int newPosition = i - d; // d is the number of rotation
if (newPosition < 0)
newPosition = length + newPosition;
newArr[newPosition] = a[i];
}
Initially i wanted to swap into the same array using the below approach but it did not work all the cases. For example where 2 array elements are being swapped due to rotation. So newPosition and position keep on pointing to each other. Hence rest of the array is not moved.
Not sure if it is possible to rotate array with O(n) complexity in the same array.
int length = a.length;
int position = length-1;
int temp = a[position];
for (int i = 0; i < length; i++){
int newPosition = position - d;
if (newPosition < 0)
newPosition = length + newPosition;
int cache = a[newPosition];
a[newPosition]= temp;
temp = cache;
position = newPosition;
}
Here is my solution in Javascript:
n is the number of elements and r is the number of rotations.
a is the array.
function rotate(a,r,n)}
for(var i = 0; i<r; i++){
var aa = array[0] //
for (var j = 0; j < n-1; j++){
array[j] = array[j+1] //
}
array[n-1] = aa //
}
return a
}
var array = [1,2,3,4,5];
console.log(rotate(array,1,5))
// Left rotation using lambda expression.
int [] ar = {1,6,7,5,9,1,34,7};
int shift =2;
int[] posAr = IntStream.range(0, ar.length).map(i->(ar[(i + (ar.length + shift)) % ar.length])).toArray();
//You can print the data
Arrays.stream(posAr).forEach(System.out::println);
enter image description here
Show code:
if(a.length==0 || a.length==1)
return a;
int r=d%a.length;
int A[]=new int[a.length];
for (int i = 0; i < a.length; i++) {
if((i+r) >= a.length)
A[i]=a[i+r-a.length];
else
A[i]=a[i+r];
}
return A;

Categories

Resources