Permutation of integers from an array given lengh - algorithm

I was interviewed a problem and after that I tested my code, found it wrong.
Not good at recursion. But I can't figure out the problem.
The question is: Given an array range from 0 ~ 9, and a length, for example, 3; generate
all permutations of integers from the given array in given length.
So, for the example:
The permutation should be: 012, 013, 014,..., 345, 346...
Below is my java code, where's the problem? (I think it's the index or the offset part)
And, if there's any better solution!
public void NumPermutation(int[] list, int offset, int[] temp, int index){
if(index == 4){
printarray(temp);
}
for(int count = offset; count < list.length; count++){
temp[index++] = list[count];
int te = list[offset];
list[offset] = list[count];
list[count] = te;
NumPermutation(list, offset, temp, index);
index -= 1;
}
}
public void test(int len){
int[] list = {0,1,2,3,4,5,6,7,8,9};
int[] temp = new int[4];
int index = 0, offset = 0;
NumPermutation(list, offset, temp,index);
}
The problem is that, the offset may increase each time and
it can't even reach the number to the end.

You need to:
Pass offset+1 to the recursive call.
Return in the if-statement.
Reverse your swap after the recursive call.
Replace the 4 with temp.length for a more generic solution.
Also preferably replace index++, index, index -= 1 with index, index + 1 and nothing.
Which results in this code: (replaced printarray with a standard print method, assuming this is Java)
public static void NumPermutation(int[] list, int offset, int[] temp, int index){
if(index == temp.length) {
System.out.println(Arrays.toString(temp));
return;
}
for(int count = offset; count < list.length; count++){
temp[index] = list[count];
// swap
int te = list[offset];
list[offset] = list[count];
list[count] = te;
NumPermutation(list, offset + 1, temp, index + 1);
// reverse swap
te = list[offset];
list[offset] = list[count];
list[count] = te;
}
}
Live demo.

Related

Recursive Merge Sort Java

I'm trying to create a recursive merge sort and I'm not sure why its not working. I have read other threads and tried debugging, but the end result is not sorted and one element would change into something else. Here's the code:
public static <E extends Comparable<E>> void mergeSort(E[] array){
mergeSortRec(array, 0, array.length-1);
}
private static <E extends Comparable<E>> void mergeSortRec(E[] array, int firstIndex, int lastIndex){
//base case: if length of array is 1
if (firstIndex == lastIndex)
//return on void method: terminates method
return;
//split the array
int mid = (firstIndex + lastIndex)/2;
//recursive case
mergeSortRec(array, firstIndex, mid);
mergeSortRec(array, mid+1, lastIndex);
merge(array, firstIndex, mid, mid+1, lastIndex );
}
private static <E extends Comparable<E>> E[] merge(E[] array, int leftFirst, int leftLast, int rightFirst, int rightLast){
//create temporary array whose size equals (rightLast - leftFirst + 1)
E tmp[] = (E[]) Array.newInstance(array.getClass().getComponentType(), rightLast - leftFirst + 1);
int indexLeft = leftFirst;
int indexRight = rightFirst;
int index = 0;
while(indexLeft < leftLast && indexRight < rightLast){
//left half element is smaller
if (array[indexLeft].compareTo(array[indexRight]) < 0){
tmp[index] = array[indexLeft];
indexLeft++;
}
//right half element is smaller
else{
tmp[index] = array[indexRight];
indexRight++;
}
index++;
}
//add remaining elements to list
while(indexLeft < leftLast){
tmp[index] = array[indexLeft];
indexLeft++;
index++;
}
while(indexRight < rightLast){
tmp[index] = array[indexRight];
indexRight++;
index++;
}
//copy tmp to list
System.arraycopy(tmp, 0, array, 0, tmp.length);
return array;
}
Since your starting and ending indexes are inclusive, this means the while conditionals in the merge function should use <=. Also, when you do the arraycopy at the end, make sure the starting index of array is leftFirst, not 0.

How to find the subarray that has sum closest to zero or a certain value t in O(nlogn)

Actually it is the problem #10 of chapter 8 of Programming Pearls 2nd edition. It asked two questions: given an array A[] of integers(positive and nonpositive), how can you find a continuous subarray of A[] whose sum is closest to 0? Or closest to a certain value t?
I can think of a way to solve the problem closest to 0. Calculate the prefix sum array S[], where S[i] = A[0]+A[1]+...+A[i]. And then sort this S according to the element value, along with its original index information kept, to find subarray sum closest to 0, just iterate the S array and do the diff of the two neighboring values and update the minimum absolute diff.
Question is, what is the best way so solve second problem? Closest to a certain value t? Can anyone give a code or at least an algorithm? (If anyone has better solution to closest to zero problem, answers are welcome too)
To solve this problem, you can build an interval-tree by your own,
or balanced binary search tree, or even beneficial from STL map, in O(nlogn).
Following is use STL map, with lower_bound().
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
int A[] = {10,20,30,30,20,10,10,20};
// return (i, j) s.t. A[i] + ... + A[j] is nearest to value c
pair<int, int> nearest_to_c(int c, int n, int A[]) {
map<int, int> bst;
bst[0] = -1;
// barriers
bst[-int(1e9)] = -2;
bst[int(1e9)] = n;
int sum = 0, start, end, ret = c;
for (int i=0; i<n; ++i) {
sum += A[i];
// it->first >= sum-c, and with the minimal value in bst
map<int, int>::iterator it = bst.lower_bound(sum - c);
int tmp = -(sum - c - it->first);
if (tmp < ret) {
ret = tmp;
start = it->second + 1;
end = i;
}
--it;
// it->first < sum-c, and with the maximal value in bst
tmp = sum - c - it->first;
if (tmp < ret) {
ret = tmp;
start = it->second + 1;
end = i;
}
bst[sum] = i;
}
return make_pair(start, end);
}
// demo
int main() {
int c;
cin >> c;
pair<int, int> ans = nearest_to_c(c, 8, A);
cout << ans.first << ' ' << ans.second << endl;
return 0;
}
You can adapt your method. Assuming you have an array S of prefix sums, as you wrote, and already sorted in increasing order of sum value. The key concept is to not only examine consecutive prefix sums, but instead use two pointers to indicate two positions in the array S. Written in a (slightly pythonic) pseudocode:
left = 0 # Initialize window of length 0 ...
right = 0 # ... at the beginning of the array
best = ∞ # Keep track of best solution so far
while right < length(S): # Iterate until window reaches the end of the array
diff = S[right] - S[left]
if diff < t: # Window is getting too small
if t - diff < best: # We have a new best subarray
best = t - diff
# remember left and right as well
right = right + 1 # Make window bigger
else: # Window getting too big
if diff - t < best # We have a new best subarray
best = diff - t
# remember left and right as well
left = left + 1 # Make window smaller
The complexity is bound by the sorting. The above search will take at most 2n=O(n) iterations of the loop, each with computation time bound by a constant. Note that the above code was conceived for positive t.
The code was conceived for positive elements in S, and positive t. If any negative integers crop up, you might end up with a situation where the original index of right is smaller than that of left. So you'd end up with a sub sequence sum of -t. You can check this condition in the if … < best checks, but if you only suppress such cases there, I believe that you might be missing some relevant cases. Bottom line is: take this idea, think it through, but you'll have to adapt it for negative numbers.
Note: I think that this is the same general idea which Boris Strandjev wanted to express in his solution. However, I found that solution somewhat hard to read and harder to understand, so I'm offering my own formulation of this.
Your solution for the 0 case seems ok to me. Here is my solution to the second case:
You again calculate the prefix sums and sort.
You initialize to indices start to 0 (first index in the sorted prefix array) end to last (last index of the prefix array)
you start iterating over start 0...last and for each you find the corresponding end - the last index in which the prefix sum is such that prefix[start] + prefix[end] > t. When you find that end the best solution for start is either prefix[start] + prefix[end] or prefix[start] + prefix[end - 1] (the latter taken only if end > 0)
the most important thing is that you do not search for end for each start from scratch - prefix[start] increases in value when iterating over all possible values for start, which means that in each iteration you are interested only in values <= the previous value of end.
you can stop iterating when start > end
you take the best of all values obtained for all start positions.
It can easily be proved that this will give you complexity of O(n logn) for the entire algorithm.
I found this question by accident. Although it's been a while, I just post it. O(nlogn) time, O(n) space algorithm. This is running Java code. Hope this help people.
import java.util.*;
public class FindSubarrayClosestToZero {
void findSubarrayClosestToZero(int[] A) {
int curSum = 0;
List<Pair> list = new ArrayList<Pair>();
// 1. create prefix array: curSum array
for(int i = 0; i < A.length; i++) {
curSum += A[i];
Pair pair = new Pair(curSum, i);
list.add(pair);
}
// 2. sort the prefix array by value
Collections.sort(list, valueComparator);
// printPairList(list);
System.out.println();
// 3. compute pair-wise value diff: Triple< diff, i, i+1>
List<Triple> tList = new ArrayList<Triple>();
for(int i=0; i < A.length-1; i++) {
Pair p1 = list.get(i);
Pair p2 = list.get(i+1);
int valueDiff = p2.value - p1.value;
Triple Triple = new Triple(valueDiff, p1.index, p2.index);
tList.add(Triple);
}
// printTripleList(tList);
System.out.println();
// 4. Sort by min diff
Collections.sort(tList, valueDiffComparator);
// printTripleList(tList);
Triple res = tList.get(0);
int startIndex = Math.min(res.index1 + 1, res.index2);
int endIndex = Math.max(res.index1 + 1, res.index2);
System.out.println("\n\nThe subarray whose sum is closest to 0 is: ");
for(int i= startIndex; i<=endIndex; i++) {
System.out.print(" " + A[i]);
}
}
class Pair {
int value;
int index;
public Pair(int value, int index) {
this.value = value;
this.index = index;
}
}
class Triple {
int valueDiff;
int index1;
int index2;
public Triple(int valueDiff, int index1, int index2) {
this.valueDiff = valueDiff;
this.index1 = index1;
this.index2 = index2;
}
}
public static Comparator<Pair> valueComparator = new Comparator<Pair>() {
public int compare(Pair p1, Pair p2) {
return p1.value - p2.value;
}
};
public static Comparator<Triple> valueDiffComparator = new Comparator<Triple>() {
public int compare(Triple t1, Triple t2) {
return t1.valueDiff - t2.valueDiff;
}
};
void printPairList(List<Pair> list) {
for(Pair pair : list) {
System.out.println("<" + pair.value + " : " + pair.index + ">");
}
}
void printTripleList(List<Triple> list) {
for(Triple t : list) {
System.out.println("<" + t.valueDiff + " : " + t.index1 + " , " + t.index2 + ">");
}
}
public static void main(String[] args) {
int A1[] = {8, -3, 2, 1, -4, 10, -5}; // -3, 2, 1
int A2[] = {-3, 2, 4, -6, -8, 10, 11}; // 2, 4, 6
int A3[] = {10, -2, -7}; // 10, -2, -7
FindSubarrayClosestToZero f = new FindSubarrayClosestToZero();
f.findSubarrayClosestToZero(A1);
f.findSubarrayClosestToZero(A2);
f.findSubarrayClosestToZero(A3);
}
}
Solution time complexity : O(NlogN)
Solution space complexity : O(N)
[Note this problem can't be solved in O(N) as some have claimed]
Algorithm:-
Compute cumulative array(here,cum[]) of given array [Line 10]
Sort the cumulative array [Line 11]
Answer is minimum amongst C[i]-C[i+1] , $\forall$ i∈[1,n-1] (1-based index) [Line 12]
C++ Code:-
#include<bits/stdc++.h>
#define M 1000010
#define REP(i,n) for (int i=1;i<=n;i++)
using namespace std;
typedef long long ll;
ll a[M],n,cum[M],ans=numeric_limits<ll>::max(); //cum->cumulative array
int main() {
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin>>n; REP(i,n) cin>>a[i],cum[i]=cum[i-1]+a[i];
sort(cum+1,cum+n+1);
REP(i,n-1) ans=min(ans,cum[i+1]-cum[i]);
cout<<ans; //min +ve difference from 0 we can get
}
After more thinking on this problem, I found that #frankyym's solution is the right solution. I have made some refinements on the original solution, here is my code:
#include <map>
#include <stdio.h>
#include <algorithm>
#include <limits.h>
using namespace std;
#define IDX_LOW_BOUND -2
// Return [i..j] range of A
pair<int, int> nearest_to_c(int A[], int n, int t) {
map<int, int> bst;
int presum, subsum, closest, i, j, start, end;
bool unset;
map<int, int>::iterator it;
bst[0] = -1;
// Barriers. Assume that no prefix sum is equal to INT_MAX or INT_MIN.
bst[INT_MIN] = IDX_LOW_BOUND;
bst[INT_MAX] = n;
unset = true;
// This initial value is always overwritten afterwards.
closest = 0;
presum = 0;
for (i = 0; i < n; ++i) {
presum += A[i];
for (it = bst.lower_bound(presum - t), j = 0; j < 2; --it, j++) {
if (it->first == INT_MAX || it->first == INT_MIN)
continue;
subsum = presum - it->first;
if (unset || abs(closest - t) > abs(subsum - t)) {
closest = subsum;
start = it->second + 1;
end = i;
if (closest - t == 0)
goto ret;
unset = false;
}
}
bst[presum] = i;
}
ret:
return make_pair(start, end);
}
int main() {
int A[] = {10, 20, 30, 30, 20, 10, 10, 20};
int t;
scanf("%d", &t);
pair<int, int> ans = nearest_to_c(A, 8, t);
printf("[%d:%d]\n", ans.first, ans.second);
return 0;
}
As a side note: I agree with the algorithms provided by other threads here. There is another algorithm on top of my head recently. Make up another copy of A[], which is B[]. Inside B[], each element is A[i]-t/n, which means B[0]=A[0]-t/n, B[1]=A[1]-t/n ... B[n-1]=A[n-1]-t/n. Then the second problem is actually transformed to the first problem, once the smallest subarray of B[] closest to 0 is found, the subarray of A[] closest to t is found at the same time. (It is kinda tricky if t is not divisible by n, nevertheless, the precision has to be chosen appropriate. Also the runtime is O(n))
I think there is a little bug concerning the closest to 0 solution. At the last step we should not only inspect the difference between neighbor elements but also elements not near to each other if one of them is bigger than 0 and the other one is smaller than 0.
Sorry, I thought I am supposed to get all answers for the problem. Didn't see it only requires one.
Cant we use dynamic programming to solve this question similar to kadane's algorithm.Here is my solution to this problem.Please comment if this approach is wrong.
#include <bits/stdc++.h>
using namespace std;
int main() {
//code
int test;
cin>>test;
while(test--){
int n;
cin>>n;
vector<int> A(n);
for(int i=0;i<n;i++)
cin>>A[i];
int closest_so_far=A[0];
int closest_end_here=A[0];
int start=0;
int end=0;
int lstart=0;
int lend=0;
for(int i=1;i<n;i++){
if(abs(A[i]-0)<abs(A[i]+closest_end_here-0)){
closest_end_here=A[i]-0;
lstart=i;
lend=i;
}
else{
closest_end_here=A[i]+closest_end_here-0;
lend=i;
}
if(abs(closest_end_here-0)<abs(closest_so_far-0)){
closest_so_far=closest_end_here;
start=lstart;
end=lend;
}
}
for(int i=start;i<=end;i++)
cout<<A[i]<<" ";
cout<<endl;
cout<<closest_so_far<<endl;
}
return 0;
}
Here is a code implementation by java:
public class Solution {
/**
* #param nums: A list of integers
* #return: A list of integers includes the index of the first number
* and the index of the last number
*/
public ArrayList<Integer> subarraySumClosest(int[] nums) {
// write your code here
int len = nums.length;
ArrayList<Integer> result = new ArrayList<Integer>();
int[] sum = new int[len];
HashMap<Integer,Integer> mapHelper = new HashMap<Integer,Integer>();
int min = Integer.MAX_VALUE;
int curr1 = 0;
int curr2 = 0;
sum[0] = nums[0];
if(nums == null || len < 2){
result.add(0);
result.add(0);
return result;
}
for(int i = 1;i < len;i++){
sum[i] = sum[i-1] + nums[i];
}
for(int i = 0;i < len;i++){
if(mapHelper.containsKey(sum[i])){
result.add(mapHelper.get(sum[i])+1);
result.add(i);
return result;
}
else{
mapHelper.put(sum[i],i);
}
}
Arrays.sort(sum);
for(int i = 0;i < len-1;i++){
if(Math.abs(sum[i] - sum[i+1]) < min){
min = Math.abs(sum[i] - sum[i+1]);
curr1 = sum[i];
curr2 = sum[i+1];
}
}
if(mapHelper.get(curr1) < mapHelper.get(curr2)){
result.add(mapHelper.get(curr1)+1);
result.add(mapHelper.get(curr2));
}
else{
result.add(mapHelper.get(curr2)+1);
result.add(mapHelper.get(curr1));
}
return result;
}
}

How to perform K-swap operations on an N-digit integer to get maximum possible number

I recently went through an interview and was asked this question. Let me explain the question properly:
Given a number M (N-digit integer) and K number of swap operations(a swap
operation can swap 2 digits), devise an algorithm to get the maximum
possible integer?
Examples:
M = 132 K = 1 output = 312
M = 132 K = 2 output = 321
M = 7899 k = 2 output = 9987
My solution ( algorithm in pseudo-code). I used a max-heap to get the maximum digit out of N-digits in each of the K-operations and then suitably swapping it.
for(int i = 0; i<K; i++)
{
int max_digit_currently = GetMaxFromHeap();
// The above function GetMaxFromHeap() pops out the maximum currently and deletes it from heap
int index_to_swap_with = GetRightMostOccurenceOfTheDigitObtainedAbove();
// This returns me the index of the digit obtained in the previous function
// .e.g If I have 436659 and K=2 given,
// then after K=1 I'll have 936654 and after K=2, I should have 966354 and not 963654.
// Now, the swap part comes. Here the gotcha is, say with the same above example, I have K=3.
// If I do GetMaxFromHeap() I'll get 6 when K=3, but I should not swap it,
// rather I should continue for next iteration and
// get GetMaxFromHeap() to give me 5 and then get 966534 from 966354.
if (Value_at_index_to_swap == max_digit_currently)
continue;
else
DoSwap();
}
Time complexity: O(K*( N + log_2(N) ))
// K-times [log_2(N) for popping out number from heap & N to get the rightmost index to swap with]
The above strategy fails in this example:
M = 8799 and K = 2
Following my strategy, I'll get M = 9798 after K=1 and M = 9978 after K=2. However, the maximum I can get is M = 9987 after K=2.
What did I miss?
Also suggest other ways to solve the problem & ways to optimize my solution.
I think the missing part is that, after you've performed the K swaps as in the algorithm described by the OP, you're left with some numbers that you can swap between themselves. For example, for the number 87949, after the initial algorithm we would get 99748. However, after that we can swap 7 and 8 "for free", i.e. not consuming any of the K swaps. This would mean "I'd rather not swap the 7 with the second 9 but with the first".
So, to get the max number, one would perform the algorithm described by the OP and remember the numbers which were moved to the right, and the positions to which they were moved. Then, sort these numbers in decreasing order and put them in the positions from left to right.
This is something like a separation of the algorithm in two phases - in the first one, you choose which numbers should go in the front to maximize the first K positions. Then you determine the order in which you would have swapped them with the numbers whose positions they took, so that the rest of the number is maximized as well.
Not all the details are clear, and I'm not 100% sure it handles all cases correctly, so if anyone can break it - go ahead.
This is a recursive function, which sorts the possible swap values for each (current-max) digit:
function swap2max(string, K) {
// the recursion end:
if (string.length==0 || K==0)
return string
m = getMaxDigit(string)
// an array of indices of the maxdigits to swap in the string
indices = []
// a counter for the length of that array, to determine how many chars
// from the front will be swapped
len = 0
// an array of digits to be swapped
front = []
// and the index of the last of those:
right = 0
// get those indices, in a loop with 2 conditions:
// * just run backwards through the string, until we meet the swapped range
// * no more swaps than left (K)
for (i=string.length; i-->right && len<K;)
if (m == string[i])
// omit digits that are already in the right place
while (right<=i && string[right] == m)
right++
// and when they need to be swapped
if (i>=right)
front.push(string[right++])
indices.push(i)
len++
// sort the digits to swap with
front.sort()
// and swap them
for (i=0; i<len; i++)
string.setCharAt(indices[i], front[i])
// the first len digits are the max ones
// the rest the result of calling the function on the rest of the string
return m.repeat(right) + swap2max(string.substr(right), K-len)
}
This is all pseudocode, but converts fairly easy to other languages. This solution is nonrecursive and operates in linear worst case and average case time.
You are provided with the following functions:
function k_swap(n, k1, k2):
temp = n[k1]
n[k1] = n[k2]
n[k2] = temp
int : operator[k]
// gets or sets the kth digit of an integer
property int : magnitude
// the number of digits in an integer
You could do something like the following:
int input = [some integer] // input value
int digitcounts[10] = {0, ...} // all zeroes
int digitpositions[10] = {0, ...) // all zeroes
bool filled[input.magnitude] = {false, ...) // all falses
for d = input[i = 0 => input.magnitude]:
digitcounts[d]++ // count number of occurrences of each digit
digitpositions[0] = 0;
for i = 1 => input.magnitude:
digitpositions[i] = digitpositions[i - 1] + digitcounts[i - 1] // output positions
for i = 0 => input.magnitude:
digit = input[i]
if filled[i] == true:
continue
k_swap(input, i, digitpositions[digit])
filled[digitpositions[digit]] = true
digitpositions[digit]++
I'll walk through it with the number input = 724886771
computed digitcounts:
{0, 1, 1, 0, 1, 0, 1, 3, 2, 0}
computed digitpositions:
{0, 0, 1, 2, 2, 3, 3, 4, 7, 9}
swap steps:
swap 0 with 0: 724886771, mark 0 visited
swap 1 with 4: 724876781, mark 4 visited
swap 2 with 5: 724778881, mark 5 visited
swap 3 with 3: 724778881, mark 3 visited
skip 4 (already visited)
skip 5 (already visited)
swap 6 with 2: 728776481, mark 2 visited
swap 7 with 1: 788776421, mark 1 visited
swap 8 with 6: 887776421, mark 6 visited
output number: 887776421
Edit:
This doesn't address the question correctly. If I have time later, I'll fix it but I don't right now.
How I would do it (in pseudo-c -- nothing fancy), assuming a fantasy integer array is passed where each element represents one decimal digit:
int[] sortToMaxInt(int[] M, int K) {
for (int i = 0; K > 0 && i < M.size() - 1; i++) {
if (swapDec(M, i)) K--;
}
return M;
}
bool swapDec(int[]& M, int i) {
/* no need to try and swap the value 9 as it is the
* highest possible value anyway. */
if (M[i] == 9) return false;
int max_dec = 0;
int max_idx = 0;
for (int j = i+1; j < M.size(); j++) {
if (M[j] >= max_dec) {
max_idx = j;
max_dec = M[j];
}
}
if (max_dec > M[i]) {
M.swapElements(i, max_idx);
return true;
}
return false;
}
From the top of my head so if anyone spots some fatal flaw please let me know.
Edit: based on the other answers posted here, I probably grossly misunderstood the problem. Anyone care to elaborate?
You start with max-number(M, N, 1, K).
max-number(M, N, pos, k)
{
if k == 0
return M
max-digit = 0
for i = pos to N
if M[i] > max-digit
max-digit = M[i]
if M[pos] == max-digit
return max-number(M, N, pos + 1, k)
for i = (pos + 1) to N
maxs.add(M)
if M[i] == max-digit
M2 = new M
swap(M2, i, pos)
maxs.add(max-number(M2, N, pos + 1, k - 1))
return maxs.max()
}
Here's my approach (It's not fool-proof, but covers the basic cases). First we'll need a function that extracts each DIGIT of an INT into a container:
std::shared_ptr<std::deque<int>> getDigitsOfInt(const int N)
{
int number(N);
std::shared_ptr<std::deque<int>> digitsQueue(new std::deque<int>());
while (number != 0)
{
digitsQueue->push_front(number % 10);
number /= 10;
}
return digitsQueue;
}
You obviously want to create the inverse of this, so convert such a container back to an INT:
const int getIntOfDigits(const std::shared_ptr<std::deque<int>>& digitsQueue)
{
int number(0);
for (std::deque<int>::size_type i = 0, iMAX = digitsQueue->size(); i < iMAX; ++i)
{
number = number * 10 + digitsQueue->at(i);
}
return number;
}
You also will need to find the MAX_DIGIT. It would be great to use std::max_element as it returns an iterator to the maximum element of a container, but if there are more you want the last of them. So let's implement our own max algorithm:
int getLastMaxDigitOfN(const std::shared_ptr<std::deque<int>>& digitsQueue, int startPosition)
{
assert(!digitsQueue->empty() && digitsQueue->size() > startPosition);
int maxDigitPosition(0);
int maxDigit(digitsQueue->at(startPosition));
for (std::deque<int>::size_type i = startPosition, iMAX = digitsQueue->size(); i < iMAX; ++i)
{
const int currentDigit(digitsQueue->at(i));
if (maxDigit <= currentDigit)
{
maxDigit = currentDigit;
maxDigitPosition = i;
}
}
return maxDigitPosition;
}
From here on its pretty straight what you have to do, put the right-most (last) MAX DIGITS to their places until you can swap:
const int solution(const int N, const int K)
{
std::shared_ptr<std::deque<int>> digitsOfN = getDigitsOfInt(N);
int pos(0);
int RemainingSwaps(K);
while (RemainingSwaps)
{
int lastHDPosition = getLastMaxDigitOfN(digitsOfN, pos);
if (lastHDPosition != pos)
{
std::swap<int>(digitsOfN->at(lastHDPosition), digitsOfN->at(pos));
++pos;
--RemainingSwaps;
}
}
return getIntOfDigits(digitsOfN);
}
There are unhandled corner-cases but I'll leave that up to you.
I assumed K = 2, but you can change the value!
Java code
public class Solution {
public static void main (String args[]) {
Solution d = new Solution();
System.out.println(d.solve(1234));
System.out.println(d.solve(9812));
System.out.println(d.solve(9876));
}
public int solve(int number) {
int[] array = intToArray(number);
int[] result = solve(array, array.length-1, 2);
return arrayToInt(result);
}
private int arrayToInt(int[] array) {
String s = "";
for (int i = array.length-1 ;i >= 0; i--) {
s = s + array[i]+"";
}
return Integer.parseInt(s);
}
private int[] intToArray(int number){
String s = number+"";
int[] result = new int[s.length()];
for(int i = 0 ;i < s.length() ;i++) {
result[s.length()-1-i] = Integer.parseInt(s.charAt(i)+"");
}
return result;
}
private int[] solve(int[] array, int endIndex, int num) {
if (endIndex == 0)
return array;
int size = num ;
int firstIndex = endIndex - size;
if (firstIndex < 0)
firstIndex = 0;
int biggest = findBiggestIndex(array, endIndex, firstIndex);
if (biggest!= endIndex) {
if (endIndex-biggest==num) {
while(num!=0) {
int temp = array[biggest];
array[biggest] = array[biggest+1];
array[biggest+1] = temp;
biggest++;
num--;
}
return array;
}else{
int n = endIndex-biggest;
for (int i = 0 ;i < n;i++) {
int temp = array[biggest];
array[biggest] = array[biggest+1];
array[biggest+1] = temp;
biggest++;
}
return solve(array, --biggest, firstIndex);
}
}else{
return solve(array, --endIndex, num);
}
}
private int findBiggestIndex(int[] array, int endIndex, int firstIndex) {
int result = firstIndex;
int max = array[firstIndex];
for (int i = firstIndex; i <= endIndex; i++){
if (array[i] > max){
max = array[i];
result = i;
}
}
return result;
}
}

Sum of factorials for large numbers

I want to calculate the sum of digits of N!.
I want to do this for really large values of N, say N(1500). I am not using .NET 4.0. I cannot use the BigInteger class to solve this.
Can this be solved by some other algorithm or procedure? Please help.
I want to do some thing like this Calculate the factorial of an arbitrarily large number, showing all the digits but in C#. However I am unable to solve.
There is no special magic that allows you to calculate the sum of the digits, as far as I am concerned.
It shouldn't be that hard to create your own BigInteger class anyway - you only need to implement the long multiplication algorithm from 3rd grade.
If your goal is to calculate the sum of the digits of N!, and if N is reasonably bounded, you can do the following without a BigInteger type:
Find a list of factorial values online (table lookup will be much more efficient than calculating from scratch, and does not require BigInteger)
Store as a string data type
Parse each character in the string as an integer
Add the resulting integers
There are two performance shortcuts that you can use for whatever implementation you choose.
Chop off any zeros from the numbers.
If the number is evenly divisible by 5^n, divide it by 10^n.
in this way,
16*15*14*13*12*11*10*9*8*7*6*5*4*3*2 = 20,922,789,888,000
//-->
16*1.5*14*13*12*11*1*9*8*7*6*0.5*4*3*2 = 20,922,789,888 //Sum of 63
Also, it feels like there should be some algorithm without reverting to calculating it all out. Going to 18!, the sums of the digits are:
2,6,6,3,9,9,9,27,27,36,27,27,45,45,63,63,63
//the sums of the resulting digits are:
2,6,6,3,9,9,9,9,9,9,9,9,9,9,9,9,9
and notably, the sum of the digits of 1500! is 16749 (the sum of whose digits are 27)
Here's some working code. Some components can be improved upon to increase efficiency. The idea is to use whatever multiplication algorithm I was told in school, and to store long integers as strings.
As an afterthought, I think it would be smarter to represent large numbers with List<int>() instead of string. But I'll leave that as an exercise to the reader.
Code Sample
static string Mult(string a, string b)
{
int shift = 0;
List<int> result = new List<int>();
foreach (int aDigit in a.Reverse().Select(c => int.Parse(c.ToString())))
{
List<int> subresult = new List<int>();
int store = 0;
foreach (int bDigit in b.Reverse().Select(c => int.Parse(c.ToString())))
{
int next = aDigit*bDigit + store;
subresult.Add(next%10);
store = next/10;
}
if (store != 0) subresult.Add(store);
subresult.Reverse();
for (int i = 0; i < shift; ++i) subresult.Add(0);
subresult.Reverse();
int newResult = new List<int>();
store = 0;
for (int i = 0; i < subresult.Count; ++i)
{
if (result.Count >= i + 1)
{
int next = subresult[i] + result[i] + store;
if (next >= 10)
newResult.Add(next % 10);
else newResult.Add(next);
store = next / 10;
}
else
{
int next = subresult[i] + store;
newResult.Add(next % 10);
store = next / 10;
}
}
if (store != 0) newResult.Add(store);
result = newResult;
++shift;
}
result.Reverse();
return string.Join("", result);
}
static int FactorialSum(int n)
{
string result = "1";
for (int i = 2; i <= n; i++)
result = Mult(i.ToString(), result);
return result.Sum(r => int.Parse(r.ToString()));
}
Code Testing
Assuming the code snippet above is in the same class as your Main method, call it thusly.
Input
static void Main(string[] args)
{
Console.WriteLine(FactorialSum(1500));
}
Output
16749
Here's a port of the C++ code you reference in one of your comments. One thing to realize when porting from C++ to C# is that integers that are zero evaluate to false and integers that are non-zero evaluate to true when used in a Boolean comparison.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ArbitraryFactorial
{
class Program
{
const int max = 5000;
static void display(int[] arr)
{
int ctr = 0;
for (int i = 0; i < max; i++)
{
if (ctr == 0 && arr[i] != 0) ctr = 1;
if (ctr != 0)
Console.Write(arr[i]);
}
}
static void factorial(int[] arr, int n)
{
if (n == 0) return;
int carry = 0;
for (int i = max - 1; i >= 0; --i)
{
arr[i] = (arr[i] * n) + carry;
carry = arr[i] / 10;
arr[i] %= 10;
}
factorial(arr, n - 1);
}
static void Main(string[] args)
{
int[] arr = new int[max];
arr[max - 1] = 1;
int num;
Console.Write("Enter the number: ");
num = int.Parse(Console.ReadLine());
Console.Write("Factorial of " + num + " is: ");
factorial(arr, num);
display(arr);
}
}
}
you can find the source code at : http://codingloverlavi.blogspot.in/2013/03/here-is-one-more-interesting-program.html
#include<stdio.h>
#include<conio.h>
#include<iostream.h>
#include<time.h>
#define max 5000
void multiply(long int *,long int);
void factorial(long int *,long int);
int main()
{
clrscr();
cout<<"PROGRAM TO CALCULATE FACTORIAL OF A NUMBER";
cout<<"\nENTER THE NUMBER\n";
long int num;
cin>>num;
long int a[max];
for(long int i=0;i<max;i++)
a[i]=0;
factorial(a,num);
clrscr();
//PRINTING THE FINAL ARRAY...:):):)
cout<<"THE FACTORIAL OF "<<num<<" is "<<endl<<endl;
long int flag=0;
int ans=0;
for(i=0;i<max;i++)
{
if(flag||a[i]!=0)
{
flag=1;
cout<<a[i];
ans=ans+a[i];
}
}
cout<<endl<<endl<<"the sum of all digits is: "<<ans;
getch();
return 1;
}
void factorial(long int *a,long int n)
{
long int lavish;
long int num=n;
lavish=n;
for(long int i=max-1;i>=0&&n;i--)
{
a[i]=n%10;
n=n/10;
}
for(i=2;i<(lavish);i++)
{
multiply(a,num-1);
num=num-1;
}
}
void multiply(long int *a,long int n)
{
for(long int i=0;i<max;i++)
a[i]=a[i]*n;
for(i=max-1;i>0;i--)
{
a[i-1]=a[i-1]+(a[i]/10);
a[i]=a[i]%10;
}
}
You can't use these numbers at all without a BigInteger type.
No algorithm or procedure can squeeze numbers larger than 264 into a long.
You need to find a BigInteger implementation for .Net 3.5.

Minimum window width in string x that contains all characters of string y

Find minimum window width in string x that contains all characters of another string y. For example:
String x = "coobdafceeaxab"
String y = "abc"
The answer should be 5, because the shortest substring in x that contains all three letters of y is "bdafc".
I can think of a naive solution with complexity O(n^2 * log(m)), where n = len(x) and m = len(y). Can anyone suggest a better solution? Thanks.
Update: now think of it, if I change my set to tr1::unordered_map, then I can cut the complexity down to O(n^2), because insertion and deletion should both be O(1).
time: O(n) (One pass)
space: O(k)
This is how I would do it:
Create a hash table for all the characters from string Y. (I assume all characters are different in Y).
First pass:
Start from first character of string X.
update hash table, for exa: for key 'a' enter location (say 1).
Keep on doing it until you get all characters from Y (until all key in hash table has value).
If you get some character again, update its newer value and erase older one.
Once you have first pass, take smallest value from hash table and biggest value.
Thats the minimum window observed so far.
Now, go to next character in string X, update hash table and see if you get smaller window.
Edit:
Lets take an example here:
String x = "coobdafceeaxab"
String y = "abc"
First initialize a hash table from characters of Y.
h[a] = -1
h[b] = -1
h[c] = -1
Now, Start from first character of X.
First character is c, h[c] = 0
Second character (o) is not part of hash, skip it.
..
Fourth character (b), h[b] = 3
..
Sixth character(a), enter hash table h[a] = 5.
Now, all keys from hash table has some value.
Smallest value is 0 (of c) and highest value is 5 (of a), minimum window so far is 6 (0 to 5).
First pass is done.
Take next character. f is not part of hash table, skip it.
Next character (c), update hash table h[c] = 7.
Find new window, smallest value is 3 (of b) and highest value is 7 (of c).
New window is 3 to 7 => 5.
Keep on doing it till last character of string X.
I hope its clear now.
Edit
There are some concerns about finding max and min value from hash.
We can maintain sorted Link-list and map it with hash table.
Whenever any element from Link list changes, it should be re-mapped to hash table.
Both these operation are O(1)
Total space would be m+m
Edit
Here is small visualisation of above problem:
For "coobdafceeaxab" and "abc"
step-0:
Initial doubly linked-list = NULL
Initial hash-table = NULL
step-1:
Head<->[c,0]<->tail
h[c] = [0, 'pointer to c node in LL']
step-2:
Head<->[c,0]<->[b,3]<->tail
h[c] = [0, 'pointer to c node in LL'], h[b] = [3, 'pointer to b node in LL'],
Step-3:
Head<->[c,0]<->[b,3]<->[a,5]<->tail
h[c] = [0, 'pointer to c node in LL'], h[b] = [3, 'pointer to b node in LL'], h[a] = [5, 'pointer to a node in LL']
Minimum Window => difference from tail and head => (5-0)+1 => Length: 6
Step-4:
Update entry of C to index 7 here. (Remove 'c' node from linked-list and append at the tail)
Head<->[b,3]<->[a,5]<->[c,7]<->tail
h[c] = [7, 'new pointer to c node in LL'], h[b] = [3, 'pointer to b node in LL'], h[a] = [5, 'pointer to a node in LL'],
Minimum Window => difference from tail and head => (7-3)+1 => Length: 5
And so on..
Note that above Linked-list update and hash table update are both O(1).
Please correct me if I am wrong..
Summary:
TIme complexity: O(n) with one pass
Space Complexity: O(k) where k is length of string Y
I found this very nice O(N) time complexity version here http://leetcode.com/2010/11/finding-minimum-window-in-s-which.html, and shortened it slightly (removed continue in a first while , which allowed to simplify condition for the second while loop). Note, that this solution allows for duplicates in the second string, while many of the above answers do not.
private static String minWindow(String s, String t) {
int[] needToFind = new int[256];
int[] hasFound = new int[256];
for(int i = 0; i < t.length(); ++i) {
needToFind[t.charAt(i)]++;
}
int count = 0;
int minWindowSize = Integer.MAX_VALUE;
int start = 0, end = -1;
String window = "";
while (++end < s.length()) {
char c = s.charAt(end);
if(++hasFound[c] <= needToFind[c]) {
count++;
}
if(count < t.length()) continue;
while (hasFound[s.charAt(start)] > needToFind[s.charAt(start)]) {
hasFound[s.charAt(start++)]--;
}
if(end - start + 1 < minWindowSize) {
minWindowSize = end - start + 1;
window = s.substring(start, end + 1);
}
}
return window;
}
Here's my solution in C++:
int min_width(const string& x, const set<char>& y) {
vector<int> at;
for (int i = 0; i < x.length(); i++)
if (y.count(x[i]) > 0)
at.push_back(i);
int ret = x.size();
int start = 0;
map<char, int> count;
for (int end = 0; end < at.size(); end++) {
count[x[at[end]]]++;
while (count[x[at[start]]] > 1)
count[x[at[start++]]]--;
if (count.size() == y.size() && ret > at[end] - at[start] + 1)
ret = at[end] - at[start] + 1;
}
return ret;
}
Edit: Here's an implementation of Jack's idea. It's the same time complexity as mine, but without the inner loop that confuses you.
int min_width(const string& x, const set<char>& y) {
int ret = x.size();
map<char, int> index;
set<int> index_set;
for (int j = 0; j < x.size(); j++) {
if (y.count(x[j]) > 0) {
if (index.count(x[j]) > 0)
index_set.erase(index[x[j]]);
index_set.insert(j);
index[x[j]] = j;
if (index.size() == y.size()) {
int i = *index_set.begin();
if (ret > j-i+1)
ret = j-i+1;
}
}
}
return ret;
}
In Java it can be implemented nicely with LinkedHashMap:
static int minWidth(String x, HashSet<Character> y) {
int ret = x.length();
Map<Character, Integer> index = new LinkedHashMap<Character, Integer>();
for (int j = 0; j < x.length(); j++) {
char ch = x.charAt(j);
if (y.contains(ch)) {
index.remove(ch);
index.put(ch, j);
if (index.size() == y.size()) {
int i = index.values().iterator().next();
if (ret > j - i + 1)
ret = j - i + 1;
}
}
}
return ret;
}
All operations inside the loop take constant time (assuming hashed elements disperse properly).
There is an O(n solution to this problem). It very well described in this article.
http://www.leetcode.com/2010/11/finding-minimum-window-in-s-which.html
Hope it helps.
This is my solution in C++, just for reference.
Update: originally I used std::set, now I change it to tr1::unordered_map to cut complexity down to n^2, otherwise these two implementations look pretty similar, to prevent this post from getting too long, I only list the improved solution.
#include <iostream>
#include <tr1/unordered_map>
#include <string>
using namespace std;
using namespace std::tr1;
typedef tr1::unordered_map<char, int> hash_t;
// Returns min substring width in which sentence contains all chars in word
// Returns sentence's length + 1 if not found
size_t get_min_width(const string &sent, const string &word) {
size_t min_size = sent.size() + 1;
hash_t char_set; // char set that word contains
for (size_t i = 0; i < word.size(); i++) {
char_set.insert(hash_t::value_type(word[i], 1));
}
for (size_t i = 0; i < sent.size() - word.size(); i++) {
hash_t s = char_set;
for (size_t j = i; j < min(j + min_size, sent.size()); j++) {
s.erase(sent[j]);
if (s.empty()) {
size_t size = j - i + 1;
if (size < min_size) min_size = size;
break;
}
}
}
return min_size;
}
int main() {
const string x = "coobdafceeaxab";
const string y = "abc";
cout << get_min_width(x, y) << "\n";
}
An implementation of Jack's idea.
public int smallestWindow(String str1, String str2){
if(str1==null || str2==null){
throw new IllegalArgumentException();
}
Map<String, Node> map=new HashMap<String, Node>();
Node head=null, current=null;
for(int i=0;i<str1.length();i++){
char c=str1.charAt(i);
if(head==null){
head=new Node(c);
current=head;
map.put(String.valueOf(c), head);
}
else{
current.next=new Node(c);
current.next.pre=current;
current=current.next;
map.put(String.valueOf(c), current);
}
}
Node end=current;
int min=Integer.MAX_VALUE;
int count=0;
for(int i=0;i<str2.length();i++){
char c = str2.charAt(i);
Node n=map.get(String.valueOf(c));
if(n!=null){
if(n.index==Integer.MAX_VALUE){
count++;
}
n.index=i;
if(n==head){
Node temp=head;
head=head.next;
if(head==null){//one node
return 1;
}
head.pre=null;
temp.pre=end;
end.next=temp;
temp.next=null;
end=temp;
}
else if(end!=n){
n.pre.next=n.next;
n.next.pre=n.pre;
n.pre=end;
n.next=null;
end.next=n;
end=n;
}
if(count==str1.length()){
min=Math.min(end.index-head.index+1, min);
}
}
}
System.out.println(map);
return min;
}
Simple java solution using the sliding window. Extending NitishMD's idea above:
public class StringSearchDemo {
public String getSmallestSubsetOfStringContaingSearchString(String toMatch,
String inputString) {
if (inputString.isEmpty() || toMatch.isEmpty()) {
return null;
}
// List<String> results = new ArrayList<String>(); // optional you can comment this out
String smallestMatch = "";
// String largestMatch = "";
int startPointer = 0, endPointer = 1;
HashMap<Character, Integer> toMatchMap = new HashMap<Character, Integer>();
for (char c : toMatch.toCharArray()) {
if (toMatchMap.containsKey(c)) {
toMatchMap.put(c, (toMatchMap.get(c) + 1));
} else {
toMatchMap.put(c, 1);
}
}
int totalCount = getCountofMatchingString(toMatchMap, toMatch);
for (int i = 0; i < inputString.length();) {
if (!toMatchMap.containsKey(inputString.charAt(i))) {
endPointer++;
i++;
continue;
}
String currentSubString = inputString.substring(startPointer,
endPointer);
if (getCountofMatchingString(toMatchMap, currentSubString) >= totalCount) {
// results.add(currentSubString); // optional you can comment this out
if (smallestMatch.length() > currentSubString.length()) {
smallestMatch = currentSubString;
} else if (smallestMatch.isEmpty()) {
smallestMatch = currentSubString;
}
// if (largestMatch.length() < currentSubString.length()) {
// largestMatch = currentSubString;
// }
startPointer++;
} else {
endPointer++;
i++;
}
}
// System.out.println("all possible combinations = " + results); // optional, you can comment this out
// System.out.println("smallest result = " + smallestMatch);
// System.out.println("largest result = " + largestMatch);
return smallestMatch;
}
public int getCountofMatchingString(HashMap<Character, Integer> toMatchMap,
String toMatch) {
int match = 0;
HashMap<Character, Integer> localMap = new HashMap<Character, Integer>();
for (char c : toMatch.toCharArray()) {
if (toMatchMap.containsKey(c)) {
if (localMap.containsKey(c)) {
if (localMap.get(c) < toMatchMap.get(c)) {
localMap.put(c, (localMap.get(c) + 1));
match++;
}
} else {
localMap.put(c, 1);
match++;
}
}
}
return match;
}
public static void main(String[] args) {
String inputString = "zxaddbddxyy由ccbbwwaay漢字由来";
String matchCriteria = "a由";
System.out.println("input=" + matchCriteria);
System.out.println("matchCriteria=" + inputString);
String result = (new StringSearchDemo())
.getSmallestSubsetOfStringContaingSearchString(matchCriteria, inputString);
System.out.println("smallest possbile match = " + result);
}
}

Resources