Time complexity of simple string concatenation - string

What is the cost of the following method. How do you calculate it?
public String joinWords(String[] words) {
String sentence = "";
for (String w : words) {
sentence = sentence + word;
}
return sentence;
}

Assuming that the cost of string concatenation is O(r + s) for two strings of lengths r and s - which historically was the case in Java but may change going forward - the runtime would be O(mn), where n is the total number of characters in the input strings and m is the number of input strings.
To see this, note that if the string lengths are n1, n2, ..., n_m, then the runtime will be
n1 + (n1 + n2) + (n1 + n2 + n3) + ... + (n1 + n2 + ... + n_m)
= m(n_1) + (m - 1)(n_2) + (m - 2)(n-3) + ... + n_m
= m(n_1 + n_2 + ... + n_m) - n_2 - 2n_3 - 3n_4 - ... - (m - 1)n_m
Subject to the constraint that n_1 + ... + n_m = n, this is maximized when n_1 = n and all the other values are 0. In that case, the runtime becomes mn, so the runtime is O(mn).

Related

check if string of parenthesis is balanced by doing certain operation on string

Given string of parenthesis we have to do 2 kinds of operation:
flip- changes the i-th parenthesis into the opposite one(left->right , right->left)
check- if the string is a balanced parenthesis expression
length of the string is at max 30000.
No of operation to be performed is at max
100000.
what kind of data structure should one use to solve this kind of problem?
Is Segment Tree a suitable data structure?
If yes how should one use it?
Example
string = ()((
no of operation=4
flip 4 {new string is ()()}
check {string is balanced}
flip 2{new string becomes ((()}
check{string is not balanced}
Let every ( be a +1 and every ) be a -1. Then a string of parenthesis is balanced iff sum for entire string is zero and sum for every range [0, k] is non-negative.
Let us define two functions for substring [i,j], sum and min. sum is obvious, and min(i,j) defined as minimum from all sum(i,k) where k <= j.
So
sum(i,k) = sum(i,j) + sum(j+1, k)
And
min(i,k) = MIN( min(i,j), sum(i,j) + min(j + 1, k) )
Now we can build a binary tree, where leafs are +1's and -1's, and root is an entire range [0, N-1]. For every node we keep min and sum.
Query for balance is obvious: we check for root.min >= 0 and root.sum == 0, so O(1).
Flip is done by updating leaf node and propagating changes to the root. No more than log(N)+1 nodes are updated, and every update is O(1), so O(logN).
A function that checks whether a string is balanced is easily made. Stepping through the string, increment a zero-initialized value if a "(" character is met and decrement it if ")" is met. If the result is 0 and it never went below 0 during the run, the string is balanced.
Flipping the parenthesis at nth position of the string is trivial.
Here's a simple implementation in javascript that flips a random character of the string in a loop and checks the validity of the resulting string after each flip.
http://jsbin.com/vagalijoca/edit?html,console
function checkbalanceness(str){
var res = 0;
for(i=0;i<str.length;i++) {
str[i]=="(" ? res++ : res--;
if (res < 0) break;
}
return res == 0;
}
function flipp(str, i){
if (i >= str.length) return str;
return str[i]=="(" ?
str.substr(0,i) + ")" + str.substr(i+1) :
str.substr(0,i) + "(" + str.substr(i+1) ;
}
//initial string
var curr = "()(())";
//operations to be executed
var ops = 40;
console.log('initial string: ' + curr + ' ' + checkbalanceness(curr));
console.log('operations: ' + ops);
console.log('start');
var ii;
var chartoflip;
for(ii=0;ii<ops;ii+=2){
chartoflip = (ii/2)%(curr.length);
curr = flipp(curr, chartoflip);
console.log((ii) + ' - flip char ' + chartoflip + ': ' + curr);
console.log((ii+1) + ' - checking ' + curr + ' ' + checkbalanceness(curr));
}
console.log('end');

Time Complexity of dependant nested loop

I've had a look at similar questions that have been asked, and have asked my classmates for advice but I am questioning the answer.
What's the time complexity of this algorithm?
for (i = 1; i < n; i *= 2)
for (j = 1; j < i; j *= 2)
\\ c elementary operations
I have been told O(log(n))^2 but from what I've read and tried it looks like O(log(n)*log(log(n))). Any help?
The inner loops repeats itself log_2(i) times for each iteration of the outer loop.
Let's sum that up then
(1) T(n) = log_2(1) + log_2(2) + log_2(4) + log_2(8) + ... + log_2(n)
(2) T(n) = sum { log_2(2^i) | i=0,1,..,log_2(n) }
(3) T(n) = sum { i * log_2(2) | i=0,1,...,log_2(n) }
(4) T(n) = 0 + 1 + ... + log_2(n)
(5) T(n) = (log_2(n) + 1)(log_2(n))/2
(6) T(n) is in O(log_2(n)^2)
Explanation:
(1) -> (2) is simply summation shorthand
(2) -> (3) is because log(a^b) = blog(a)
(3) -> (4) log_2(2) = 1
(4) -> (5) Sum of arithmetic progression
(5) -> (6) is giving asymptotic notation

Change strings to make them equal

Referring to question HERE
We have two strings A and B with the same super set of characters. We
need to change these strings to obtain two equal strings. In each move
we can perform one of the following operations:
1- swap two consecutive characters of a string
2- swap the first and
the last characters of a string
A move can be performed on either string. What is the minimum number
of moves that we need in order to obtain two equal strings? Input
Format and Constraints: The first and the second line of the input
contains two strings A and B. It is guaranteed that the superset their
characters are equal. 1 <= length(A) = length(B) <= 2000 All the
input characters are between 'a' and 'z'
It looks like this will have to solved using dynamic programming. But I am not able to come up with equations. Some one has suggested them in answer - but it does not look all right.
dp[i][j] =
Min{
dp[i + 1][j - 1] + 1, if str1[i] = str2[j] && str1[j] = str2[i]
dp[i + 2][j] + 1, if str1[i] = str2[i + 1] && str1[i + 1] = str2[i]
dp[i][j - 2] + 1, if str1[j] = str2[j - 1] && str1[j - 1] = str2[j]
}
In short, it's
dp[i][j] = Min(dp[i + 1][j - 1], dp[i + 2][j], dp[i][j - 2]) + 1.
Here dp[i][j] means the number of minimum swaps needs to swap str1[i, j] to str2[i, j]. Here str1[i, j] means the substring of str1 starting from pos i to pos j :)
Here is an example like the one in the quesition,
str1 = "aab",
str2 = "baa"
dp[1][1] = 0 since str1[1] == str2[1];
dp[0][2] = str1[0 + 1][2 - 1] + 1 since str1[0] = str2[2] && str1[2] = str2[0].
You have two atomic operations:
swap consecutive with cost 1
swap first and last with cost 1
One interesting fact:
and 2. are the same if the strings end would be attached to the strings begin (circular string)
So we can derive a more generic operation
move a character with cost = |from - to| (across borders)
The problem rather seems not 2-dimensional to me, or yet I cannot determine the dimensions. Take this algorithm as naive approach:
private static int transform(String from, String to) {
int commonLength = to.length();
List<Solution> worklist = new ArrayList<>();
worklist.add(new Solution(0,from));
while (!worklist.isEmpty()) {
Solution item = worklist.remove(0);
if (item.remainder.length() == 0) {
return item.cost;
} else {
int toPosition = commonLength - item.remainder.length();
char expected = to.charAt(toPosition);
nextpos : for (int i = 0; i < item.remainder.length(); i++) {
if (item.remainder.charAt(i) == expected) {
Solution nextSolution = item.moveCharToBegin(i, commonLength);
for (Solution solution : worklist) {
if (solution.remainder.equals(nextSolution.remainder)) {
solution.cost = Math.min(solution.cost, nextSolution.cost);
continue nextpos;
}
}
worklist.add(nextSolution);
}
}
}
}
return Integer.MAX_VALUE;
}
private static class Solution {
public int cost;
public String remainder;
public Solution(int cost, String remainder) {
this.cost = cost;
this.remainder = remainder;
}
public Solution moveCharToBegin(int i, int length) {
int costOffset = Math.min(i, length - i); //minimum of forward and backward circular move
String newRemainder = remainder.substring(0, i) + remainder.substring(i + 1);
return new Solution(cost + costOffset, newRemainder);
}
}

How to Find a Point Where a Circle and Line with 1/0 Slope Intersect

I'm writing a simple 2D top-down game in Python 3 using tkinter. All the collidable objects are either circles/arcs or lines. I wrote the following method to detect when a circle hits a line:
I am using the formulas y = mx + b and r^2 = (x-h)^2 + (y-k)^2
def CheckHitCToL(self, LX0, LY0, LX1, LY1, CX0, CX1, Tab):
try:
H = self.Creatures[Tab].X
K = self.Creatures[Tab].Y
R = abs((CX0 - CX1) / 2)
M = (LY0 - LY1) / (LX0 - LX1)
B = M * (-LX1) + LY1
QA = (M * M) + 1
QB = (-H - H) + (((B - K) * M) * 2)
QC = (H * H) + ((B - K) * (B - K)) - (R * R)
X = (- QB + sqrt((QB * QB) - (4 * QA * QC))) / (2 * QA)
Y = (M * X) + B
if ((X <= LX0 and X >= LX1) or (X >= LX0 and X <= LX1)) and ((Y <= LY0 and Y >= LY1) or (Y >= LY0 and Y <= LY1)):
return True
else:
return False
except:
return False
My problem is when you have a vertical line, M (Or the slope) is (LY0 - LY1) / 0. (This is because the slope is equal to rise/run, and vertical lines don't have a run, just a rise) Which of course returns an error, caught by try except, which then informs my movement method that no collision has taken place. Of course I can simply move the "try:" down a few lines, but it's still going to throw an error. How can I adapt this program to not throw an error when working with a vertical line?
Well, the most obvious method would involve using if( (LX0 - LX1)==0 ) and doing this case separately. In such cases, you need to check whether distance between LX0 and CX0 is equal to the radius of circle.
You can use another forms of line equation -
implicit A*x + B*y + C = 0
or parametric x = LX0 + t * (LX1 - LX0), y = LY0 + t *(LY1 - LY0)
with appropriate modification of calculations

Beginner: concat a string from different primitives

Apologies, as I'm sure this is a stupid question, but...
Please could anyone explain to me why this:
public class java {
public static void main(String[] args) {
byte zero = 0;
short one = 1;
int three = 3;
long one2 = 1;
float onepointnought = 1.0f;
double onedotnone = 1.0;
char letterh = 'H';
char letterw = 'w';
char letterr = 'r';
char letterd = 'd';
boolean bool = true;
String output = letterh + three + one + one2 + zero + " " + letterw + zero + letterr + one + letterd + " " + (onepointnought+onedotnone) + " " + bool;
System.out.println(output);
} }
Is outputting:
77 w0r1d 2.0 true
I'm expecting it to say "H3ll0 w0r1d 2.0 true"
It's from the interactive online java tutorials over at http://www.learnjavaonline.org/
Thanks!
Neil.
In this sentence
String output = letterh + three + one + one2 + zero + " " + letterw + zero + letterr + one + letterd + " " + (onepointnought+onedotnone) + " " + bool;
the letterh contains 'H' whose ASCII value is 72 & the addition of three + one + one2 + zero is 5 because these are non-string variables, so it is displaying (72 + 5)77 in the result,
you must convert three , one , one2 , zero to sting variable

Resources