I was trying to find time complexity of these 2 codes but i am not sure about my answers .
code1
int i = 1;
int count = 0;
while (i < n) {
for (int j = 0; j < i; j++) {
count++;
}
i *= 2;
}
I calculated the number of steps in loops and I reached to (log n)^2 but i am not sure about it .
Code2
int k=0;
for (int i = 2; i <= n; i++) {
for (int j = 2; j * j <= i; j++) {
if (i % j == 0) {
k++;
break;
}
}
}
and for this one I got ( n * log n)
actually I am new to calculating time complexity and I am not sure about them , could you help me find the correct answer .
Related
I'm practicing coding on HackerRank, and I have the following code, which gets a different outputs.
The task is the following:
Given an array of integers, find the longest subarray where the absolute difference between any two elements is less than or equal to.
Example:
a = [1,1,2,2,4,4,5,5,5];
There are two subarrays meeting the criterion: [1,1,2,2] and [4,4,5,5,5]. The maximum length subarray has 5 elements.
The following code gets the desired output:
public static int pickingNumbers(List<Integer> a) {
// Write your code here
int max = 0;
int counter = 0;
Collections.sort(a);
for(int i = 0; i < a.size(); i++){
for(int j = i+1; j< a.size(); j++){
if(Math.abs(a.get(i)-a.get(j)) <= 1){
counter++;
}
}
if(counter > max)
max = counter;
counter = 0;
}
return max+1;
}
While this one, gets a different output -
public static int pickingNumbers(List<Integer> a) {
// Write your code here
int max = 0;
int counter = 0;
Collections.sort(a);
for(int i = 0; i < a.size(); i++){
for(int j = i+1; j< a.size(); j++){
if(Math.abs(a.get(i)-a.get(j)) <= 1){
counter++;
}
}
if(counter > max){
max = counter;
counter = 0;
}
}
return max+1;
}
As you can see, the difference between the 2 codes are just the brackets after the if(counter > max) part. In the latter case, the counter is always 1 unit more than it should be.
Can anyone please explain it to me, why the code behaves different in this case?
It's because in the first snippet counter = 0; is not in the if block.
When if is not enclosed in brackets, it only evaluates the first instruction after it, so the counter = 0; is always executed.
Here's an example with better indentation:
public static int pickingNumbers(List<Integer> a)
{
int max = 0;
int counter = 0;
Collections.sort(a);
for(int i = 0; i < a.size(); i++)
{
for(int j = i+1; j< a.size(); j++)
{
if(Math.abs(a.get(i)-a.get(j)) <= 1)
{
counter++;
}
}
if(counter > max)
max = counter;
counter = 0; // Not in the if statement, so the counter is always reset!
}
return max+1;
}
const genObj = (ar) => {
let obj = {}
for(let i of ar) {
!(obj[i])? obj[i] = 1 : obj[i]++
}
return obj
}
function pickingNumbers(a) {
// Write your code here
let obj = genObj(a)
let k = Object.keys(genObj(a))
let i = 0
let max = 0
while (i <= k.length - 1) {
for(let j = i; j <= k.length - 1; j++){
if(i === j) continue
if(Math.abs(k[i] - k[j]) <= 1) {
if(obj[k[i]] + obj[k[j]] > max)
max = obj[k[i]] + obj[k[j]]
}
}
i++
}
return max > Math.max(...Object.values(obj)) ? max : Math.max(...Object.values(obj))
}
I'm a beginner at Java.
I was solving nested for loop questions... Then this question came up. After research and re-tries I couldn't get my head around it. It must be solved using only nested for loops.
This is what the question wants my code to output:
-----1-----
----333----
---55555---
--7777777--
-999999999-
This is as close as I got:
---------1
-------333
-----55555
---7777777
-999999999
This is my code:
for (int line = 1; line <= 9; line+=2) {
for (int j = 1; j <= (-1 * line + 10); j++) {
System.out.print("-");
}
for (int k = 1; k <= line; k++) {
System.out.print(line);
}
System.out.println();
}
You just need to add another for loop to print - on the right side.
Also now the first and the third loop will execute for half the number of times
for (int line = 1; line <= 9; line+=2) {
for (int j = 0; j <= (-1 * line + 10) / 2; j++) {
System.out.print("-");
}
for (int k = 1; k <= line; k++) {
System.out.print(line);
}
for (int j = 0; j <= (-1 * line + 10) / 2; j++) {
System.out.print("-");
}
System.out.println();
}
I am trying to solve this question:
Given an integer array, adjust each integers so that the difference of
every adjacent integers are not greater than a given number target.
If the array before adjustment is A, the array after adjustment is B,
you should minimize the sum of `| A[i]-B[i] |. You can assume each number in the array is a positive integer and not greater than 100.
`
I see a dp solution but I don't quite understand the recurrence equation.
public static int MinAdjustmentCost(ArrayList<Integer> A, int target) {
// write your code here
if (A == null || A.size() == 0) {
return 0;
}
// D[i][v]: 把index = i的值修改为v,所需要的最小花费
int[][] D = new int[A.size()][101];
int size = A.size();
for (int i = 0; i < size; i++) {
for (int j = 1; j <= 100; j++) {
D[i][j] = Integer.MAX_VALUE;
if (i == 0) {
// The first element.
D[i][j] = Math.abs(j - A.get(i));
} else {
for (int k = 1; k <= 100; k++) {
// 不符合条件
if (Math.abs(j - k) > target) {
continue;
}
int dif = Math.abs(j - A.get(i)) + D[i - 1][k];
D[i][j] = Math.min(D[i][j], dif);
}
}
}
}
int ret = Integer.MAX_VALUE;
for (int i = 1; i <= 100; i++) {
ret = Math.min(ret, D[size - 1][i]);
}
return ret;
}
Could someone explain it to me?
You need to minimize the cost of the adjustment, which is the value you increase/decrease every element such that the difference between every adjacent elements is less than or equal to target. The dp solution is to try every possible value and minimize the cost on the valid ones (when abs(A[i]-A[i-1]) <= target)
First thing is to fill the cost for adjusting first element to 1-100 which is done here:
for (int i = 0; i < size; i++) {
for (int j = 1; j <= 100; j++) {
D[i][j] = Integer.MAX_VALUE; // fill with MAX_VALUE because we want to minimize
if (i == 0) {
// for the first element we just set the cost of adjusting A[i] to j
D[i][j] = Math.abs(j - A.get(i));
}
Now you have D[0][j] as the cost to adjust the first element to be j. Then for every other element, you loop again (from k = 1 to k = 100) for other elements and try to change A[i] to j. And then you check if abs(k-j) is valid (less than or equal to target) then you can adjust A[i] to be j and A[i-1] to be k so you minimize on D[i][j].
Here D[i][j] means the cost of changing A[i] to j and D[i-1][k] is the cost of changing A[i-1] to k. so for every k and j if they are valid (abs(k-j)<=target) then you add them together and minimize the value saved in D[i][j] so you can use it for next element, which is done here:
else {
for (int k = 1; k <= 100; k++) {
// if abs(j-k) > target then changing A[i] to j isn't valid (when A[i-1] is k)
if (Math.abs(j - k) > target) {
continue;
}
// otherwise, calculate the the cost of changing A[i] to j and add to it the cost of changing A[i-1] to k
int dif = Math.abs(j - A.get(i)) + D[i - 1][k];
// minimize D[i][j]
D[i][j] = Math.min(D[i][j], dif);
}
}
At the end, you need to loop from 1 to 100 at the last element and check which is the minimum value over all, which is done here:
int ret = Integer.MAX_VALUE;
for (int i = 1; i <= 100; i++) {
ret = Math.min(ret, D[size - 1][i]);
}
I think if you split the initialization code and the DP calculation code it would be easier to understand, for example:
// fill the initial values
for (int i = 0; i < size; ++i) {
for (int j = 1; j <= 100; ++j) {
// on the first element just save the cost of changing
// A[i] to j
if (i == 0) {
DP[i][j] = abs(j-A.get(i));
} else {
// otherwise intialize with MAX_VALUE
D[i][j] = Integer.MAX_VALUE;
}
}
}
for (int i = 1; i < size; i++) {
for (int j = 1; j <= 100; j++) {
for (int k = 1; k <= 100; k++) {
// if abs(j-k) isn't valid skip it
if (Math.abs(j - k) > target) {
continue;
}
// if it is valid, calculate the cost of changing A[i] to j
// and add it to the cost of changing A[i-1] to k then minimize
// over all values of j and k
int dif = Math.abs(j - A.get(i)) + D[i - 1][k];
D[i][j] = Math.min(D[i][j], dif);
}
}
}
// calculate the minimum cost at the end
int ret = Integer.MAX_VALUE;
for (int i = 1; i <= 100; i++) {
ret = Math.min(ret, D[size - 1][i]);
}
I need to print a table that looks like this if the user entered a 5 using nested for loops:
****5
***45
**345
*2345
12345
I've been working on this for hours and the closest I got was:
int size = scan.nextInt();
for (int i = 1; i <= size; i++)
{
for (int star = size-1; star >= i; star--)
System.out.print("*");
for (int k = 1; k <= i; k++)
System.out.print(i);
System.out.println();
}
Which outputs this:
****1
***12
**123
*1234
12345
You have too many loops; I find it easier to reason about zero based looping so I'm going to use that. Iterate i and j from 0 to size. If j + 1 is greater than size - i - 1 then we want to print j + 1. Otherwise, we want a star. Like,
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (j + 1 > size - i - 1) {
System.out.print(j + 1);
} else {
System.out.print('*');
}
}
System.out.println();
}
For size = 5 that outputs (as requested)
****5
***45
**345
*2345
12345
If you simply must have one based indices, that would be
for (int i = 1; i <= size; i++) {
for (int j = 1; j <= size; j++) {
if (j > size - i) {
System.out.print(j);
} else {
System.out.print('*');
}
}
System.out.println();
}
If you want to keep your loops and avoid if statements, you can tweak last loop by changing
for (int k = 1; k <= i; k++)
into
for (int k = 1+size-i; k <= size; k++)
Btw I also find it way easier to start loops from 0, so updated code would look like this:
int size = scan.nextInt();
for (int i = 0; i < size; i++)
{
for (int star = size-1; star > i; star--)
System.out.print("*");
for (int k = size-i; k <= size; k++)
System.out.print(k);
System.out.println();
}
I hope it helps
This question already has answers here:
How can I find the time complexity of an algorithm?
(10 answers)
Closed 5 years ago.
how do you get the time complexity of the functions count and printall in ThreeSum.java?
public static void printAll(int[] a) {
int n = a.length;
for (int i = 0; i < n; i++) {
for (int j = i+1; j < n; j++) {
for (int k = j+1; k < n; k++) {
if (a[i] + a[j] + a[k] == 0) {
System.out.println(a[i] + " " + a[j] + " " + a[k]);
}
}
}
}
}
public static int count(int[] a) {
int n = a.length;
int count = 0;
for (int i = 0; i < n; i++) {
for (int j = i+1; j < n; j++) {
for (int k = j+1; k < n; k++) {
if (a[i] + a[j] + a[k] == 0) {
count++;
}
}
}
}
Although time complexity questions are sometimes very tough but this one is an easy cake. You can simply check it out as follows,
for (int i = 0; i < n; i++) // it runs for n times
for (int j = i+1; j < n; j++) // it runs for n-i-1 time
for (int k = j+1; k < n; k++) // it runs for n-j-1 times
Now since they are nested loops that means each of inner loop runs as many number of times as outer loop.
total = n * ( n-i-1 ) * ( n-j-1 )
= n^3 ... // ignoring all other lower power terms
So time complexity of this code will be O(n^3).