Friday, February 6, 2026

Simple Linear Regression With Example

Regression analysis is one of the most used ways for predictions. With in the regression analysis, linear regression is considered the starting point of the machine learning.

A linear regression is a statistical technique used to find the relationship between variables. There is a dependent variable (target) and one or more independent variables (predictors). In terms of machine learning you want to model the relationship between features and a label. Linear regression assumes this relationship is linear, meaning it can be represented by a straight line.

Simple Linear Regression

Simple linear regression is a linear regression which finds the causal relationship between two variables.

  1. One variable, generally denoted as x is the independent variable or predictor.
  2. Another variable, generally denoted by y is the dependent variable or target.

For example, if we want to find the relationship between years of experience and salary then years of experience is the independent variable and salary is the dependent variable and we want to find the causal relationship between years of experience and salary with the understanding that with increasing experience salary also increases.

If you have years of experience and salary data, you can use it to fit a simple linear regression model. Once that "learning" is done you can predict the salary by passing the years of experience.

Simple Linear Regression equation

In context of machine learning where we have sample data and we use it to create regression model, simple linear regression equation is as given below.

$$ \hat{y} = b_{0} + b_{1}X_{1} $$

Here \(\hat{y}\) is the predicted label - Output

b0 is the intercept, which tells you where the regression line intercepts the Y-axis. Or you can say it is the value when independent variable (x) is 0.

b1 is the slope. It tells how much dependent variable changes for one unit change in independent variable.

Simple Linear Regression

Ordinary Least Squares (OLS) estimation

In the above image, the regression line is labelled as the best fit line. But how do we know that this line is the best fit line. There are many straight lines that can be drawn going through the x values and intercepting the y axis. One way to find the best- fit line is by using the ordinary least squares estimation.

Ordinary least squares work by minimizing the sum of the squared differences between the observed values (the actual data points) and the values predicted by the model (lying on the regression line).

If actual value is yi and the predicted value is \(\hat{y_i}\) then the residual = \(y_{i} - \hat{y_i}\).

Squaring these differences ensures that both positive and negative residuals are treated equally. So, the best-fit line is the line for which the sum of the squared of the residuals (RSS) is minimum.

$$ RSS = \sum_{i=1}^{n} (y_{i}-\hat{y}{i})^2 $$

OLS

Formula for slope and intercept

The formula for calculating slope is-

\(b_{1}=r*\frac{s_{y}}{s_{x}}\)

Where: \(r\) = Pearson's correlation coefficient between \(x\) and \(y\).

\(s_{y}\) = Standard deviation of the \(y\) variable.

\(s_{x}\) = Standard deviation of the \(x\) variable.

Formula for intercept is

\(b_0=\bar{y} - b_1\*\bar{x}\) meaning (Mean of \(y\) - Slope \(\times \) Mean of \(x\))

After replacing the value of b1

\( b_0=\bar{y} - r\frac{s_{y}}{s_{x}} \times \bar{x}\)

Simple linear regression by manually calculating slope and intercept

Though scikit-learn library implements ordinary least squares (OLS) linear regression and that is the way to model simple linear regression in ML using Python but let's try to do it manually by using the above mentioned formulas first. This code still uses other Python libraries like Pandas, Numpy and Matplotlib.

Salary dataset used here can be downloaded from this URL- https://www.kaggle.com/datasets/abhishek14398/salary-dataset-simple-linear-regression

1. Importing libraries and reading CSV file
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# reading dataset from current directory
df = pd.read_csv("./Salary_dataset.csv")
print(df.head())

On printing using head() function first five rows are displayed

Unnamed: 0  YearsExperience   Salary
          0              1.2  39344.0
          1              1.4  46206.0
          2              1.6  37732.0
          3              2.1  43526.0
          4              2.3  39892.0

As you can see there is serial number also for which column name is "Unnamed: 0 ". This column name is not needed so let's drop it.

#Removing serial no column
df = df.drop("Unnamed: 0", axis=1)

2. Calculating the values for equation.

#Calculate mean and standard deviation
mean_year = df['YearsExperience'].mean()
mean_salary = df['Salary'].mean()
std_year = df['YearsExperience'].std()
std_salary = df['Salary'].std()
# correlation coefficient between Years of experience and salary
corr = df['YearsExperience'].corr(df['Salary'])

print(corr) # 0.9782416184887599
# calculate slope
slope = corr * std_salary/std_year
print(slope)
# calculate intercept
intercept = mean_salary - (slope * mean_year)
print(intercept)

3. Predicting values

# get predicted salaries
y_pred = intercept + slope * df['YearsExperience']

# concatenate two panda series for actual salaries and predicted salaries
combined_array = np.column_stack((df['Salary'].round(2), y_pred.round(2)))
# check displayed values 
print(combined_array)

#Predict salary for given years of experience
sal_pred = intercept + slope * 11
print(sal_pred) # 128797.78950252903

4. Plotting the regression line

#Plot regression line
# Scatter plot for actual values
plt.scatter(df['YearsExperience'], df['Salary'], color='blue', label='Actual')
# Plot the regression line
plt.plot(df['YearsExperience'], y_pred, color='red', label='Regression Line')
plt.xlabel('Years of experience')
plt.ylabel('Salary')
plt.title('Years of experience Vs Salary')
plt.legend()
plt.show()

Simple linear regression using scikit-learn Python library

The above example shows how to calculate slope and intercept manually for linear regression but scikit-learn provides in-built support for creating linear regression model. Let's go through the steps.

1. Importing libraries and data pre-processing

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# read CSV file
df = pd.read_csv("./Salary_dataset.csv")
# remove serial no. column
df = df.drop("Unnamed: 0", axis=1)

2. As a second step we do feature selection and splitting the data into two sets; training data and test data. Sklearn has inbuilt support for splitting.

# Feature and label selection
X = df['YearsExperience']
y = df['Salary']

As a convention in the ML code, capital X is used for the input data because it represents a matrix of features, while lowercase y is used for the target because it is typically a vector. Splitting is done using train_test_split where test_size is passed as 0.2, meaning 20% of the data is used as test data whereas 80% of the data is used to train the model.

from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score 
# splitting data into test data (80%) and train data (20%)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

3. Training the model

From sklearn you import the LinearRegression class which is an implementation of Ordinary least squares Linear Regression. Later you have to create an object of this class and call the fit method to train the model, parameters passed to the fit method are training data (X_train in our case) and target values (y_train in our case)

from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score 
# splitting data into test data (80%) and train data (20%)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
#scikit-learn models require a 2D array input for features (X), even for a single feature
#so reshape(-1, 1) is used to convert to 2D array
X_train_reshaped = X_train.values.reshape(-1, 1)
reg = LinearRegression()

# Train the model on the training data
reg.fit(X_train_reshaped, y_train)

# Print intercept and coefficient
print('Intercept (b0) is', reg.intercept_)
print('Weight (b1) is', reg.coef_[0])

Which gives the following output for intercept and coefficient.

Intercept (b0) is 24380.20147947369
Weight (b1) is 9423.81532303098

4. Once the model is trained, predictions can be made using test data which can then be compared with the actual test data (y_test)

# predict values for the test data
y_pred= reg.predict(X_test.values.reshape(-1,1))

combined_data = pd.DataFrame({'Actual Salaries':y_test, 'Predicted Salaries':y_pred})
print(combined_data)

combined_data gives both actual values and predicted values side by side.

    Actual Salaries  Predicted Salaries
27         112636.0       115791.210113
15          67939.0        71499.278095
23         113813.0       102597.868661
17          83089.0        75268.804224
8           64446.0        55478.792045
9           57190.0        60190.699707

5. You can also predict salary by passing year.

#Predict salary for given years of experience
sal_pred =  model.predict([[11]])
print(sal_pred) # 128042.17003281

6. Seeing the model metrics such as R squared, mean squared error and root mean squared error.

print("R2 score", r2_score(y_test,y_pred)) 
mse = mean_squared_error(y_test, y_pred)
print("Mean Squared Error", mse)
print("Root Mean Squared Error", np.sqrt(mse))

7. Plotting the regression line

# Scatter plot for actual values
plt.scatter(X_test, y_test, color='blue', label='Actual')
# Plot the regression line
plt.plot(X_test, y_pred, color='red', label='Regression Line')
plt.xlabel('Years of experience')
plt.ylabel('Salary')
plt.title('Years of experience Vs Salary')
plt.legend()
plt.show()
RegressionPlot

That's all for this topic Simple Linear Regression With Example. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Python Tutorial Page


Related Topics

  1. Python Installation on Windows
  2. Encapsulation in Python
  3. Method Overriding in Python
  4. Multiple Inheritance in Python
  5. Mean, Median and Mode With Python Examples

You may also like-

  1. Passing Object of The Class as Parameter in Python
  2. Local, Nonlocal And Global Variables in Python
  3. Python count() method - Counting Substrings
  4. Python Functions : Returning Multiple Values
  5. Marker Interface in Java
  6. Functional Interfaces in Java
  7. Difference Between Checked And Unchecked Exceptions in Java
  8. Race Condition in Java Multi-Threading

Mean, Median and Mode With Python Examples

This post explains Mean, Median and Mode which are measures of central tendency and help to summarize the data. Here measure of central tendency is a value which identifies the middle position with in a set of data.

Here we'll look at how to calculate mean, median and mode and which one is more appropriate in the given scenario.

Mean

Mean, which is the arithmetic average is calculated by summing all the values in the data set divided by the number of values in the data set. If there are n values ranging from \(x_1, x_2, \dots, x_n \) then the mean \( \overline{x} \) (x bar) is calculated as:

$$ \bar{x} = \frac{x_1 + x_2 + \cdots + x_n} {n}$$

Using summation notation same thing can be written as:

$$ \bar{x} = \frac{1}{n} \sum_{i=1}^{n} x_i $$

For example, if we have a data set of 10 values as given below-

5, 8, 12, 15, 18, 20, 22, 25, 30, 35

Then the sum of the values is-

5 + 8 + 12 + 15 + 18 + 20 + 22 + 25 + 30 + 35 = 190

And the mean is \( \overline{x} \) = 190/10 = 19

Mean is a better choice when data is normally distributed.

When mean is not a better choice

Mean may not be a best choice when data is skewed as mean is sensitive to outliers. In skewed data, outliers (very high or low values) can drag the mean away from the center.

For example, if values are- 10, 12, 13, 14, 15, 100

Then the mean is- 164/6 = 27.33

As you can see mean is pulled away from the center because of one extreme value 100. In such cases median is better option.

Median

Median is the middle value in an ordered (ascending or descending) set of data. Formula for median is as given below-

  1. If the dataset has an odd number of values, it is the middle value. $$\left(\frac{n+1}{2}\right)^\text{th}\text{value} $$
  2. If the dataset has an even number of values, it is the average of the two middle values. $$ \text{Median} = \frac{\left(\frac{n}{2}\right)^\text{th}\text{value} + \left(\left(\frac{n}{2}\right)+1\right)^\text{th}\text{value}}{2} $$

For example, in order to calculate median for

5, 15, 18, 20, 22, 35, 8, 12, 25, 30

First sort them in ascending order-

5, 8, 12, 15, 18, 20, 22, 25, 30, 35

Number of values is 10 (even) so the median is-

\(\frac{\left(\frac{10}{2}\right)\text{th value} + \left(\left(\frac{10}{2}\right)+1\right)\text{th value}}{2} = \frac{5^{\text{th}} \text{ value} + 6^{\text{th}} \text{ value}}{2} \) = (18+20)/2 = 19

So, the median of the dataset is 19.

Median responds well to the skewed data

Earlier we have seen that the mean is sensitive to the outliers whereas median doesn't vary.

For example, if values are- 10, 12, 13, 14, 15, 100

Then the median = (13 + 14)/2 = 13.5

Which is close to center.

Mode

The mode is the most frequent value in the dataset. For example, if we have the following list of values

2, 4, 4, 5, 7, 7, 7, 8, 9, 10

Then 7 is the mode as that has the highest frequency 3.

Mode is not sensitive to outliers.

We may have a scenario where all values appear exactly once meaning no mode. We may also have a scenario where 2 or more values have the same frequency meaning multiple modes.

Mode is the best measure of central tendency when you're dealing with categorical data (non-numerical), or when you want to identify the most common value in a dataset. For example, you want to find the most shopped brand or most preferred colour.

When you want the most typical value, for example most bought shoe size.

Shoe sizes: [7, 8, 8, 8, 9, 10]

Here mode = 8 (most common size)

Calculating mean, median, mode using Python libraries

1. NumPy library has mean and median functions to calculate mean and median. For mode SciPy library provides mode method.

import numpy as np
from scipy import stats
values = [2, 4, 4, 5, 7, 7, 7, 8, 9, 10]
#Mean and Median
mean = np.mean(values)
median = np.median(values)
print('Mean is', mean)
print('Median is', median)
#Mode = returns an array of mode and count
mode = stats.mode(values)
print('Mode is', mode[0], 'count is', mode[1])

Output

Mean is 6.3
Median is 7.0
Mode is 7 count is 3

2. Using Pandas library which has mean, median and mode functions. You can convert list of values to Pandas series and then calculate mean, median and mode.

import pandas as pd
values = [2, 4, 4, 4, 5, 7, 7, 7, 8, 9, 10]
data = pd.Series(values)
mean = data.mean()
median = data.median()
# returns a Series (which can have multiple modes)
mode = data.mode()
print(f"Mean is {mean:.2f}")
print('Median is', median)
print('Mode is', list(mode))

Output

Mean is 6.09
Median is 7.0
Mode is [4, 7]

That's all for this topic Mean, Median and Mode With Python Examples. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Python Tutorial Page


Related Topics

  1. Python Installation on Windows
  2. Encapsulation in Python
  3. Method Overriding in Python
  4. Multiple Inheritance in Python
  5. Simple Linear Regression With Example

You may also like-

  1. Passing Object of The Class as Parameter in Python
  2. Local, Nonlocal And Global Variables in Python
  3. Python count() method - Counting Substrings
  4. Python Functions : Returning Multiple Values
  5. Marker Interface in Java
  6. Functional Interfaces in Java
  7. Difference Between Checked And Unchecked Exceptions in Java
  8. Race Condition in Java Multi-Threading

Monday, December 1, 2025

Coin Change - Min Number of Coins Needed - Java Program

In this article we'll see how to write a Java program for the coin change problem, which states that "Given an array of coins storing coins of different denominations and an integer sum representing an amount. Find the minimum number of coins needed to make that sum. If that amount of money cannot be made up by any combination of the coins, return -1."

Any coin can be used any number of times.

For example-

1. Input: int coins[] = {9, 6, 5, 1}, sum = 101
Output: 12
How: 9 (10 times) + 6 + 5

2. Input: int coins[] = {1, 2, 5}, sum = 11
Output: 3
How: 5 + 5 + 1

3. Input: int coins[] = {2}, sum = 0
Output: 0

The "coin change" problem is a good example of dynamic programming as you can break this problem into smaller overlapping sub-problems and you can also store the result of those subproblems (memoization) to avoid redundant calculations.

Coin change problem Java Program

The program for finding the minimum number of coins that add to the given sum can be written using

  1. Recursion without any optimization.
  2. You can add memoization with recursion to make it faster this is also called top-down approach in dynamic programming.
  3. You can also use bottom-up approach also known as tabular form. In bottom-up approach you try to solve the sub-problems first and use their solutions to arrive at solutions to bigger sub-problems.

We'll write java programs for all these three approaches here.

1. Using recursion

Here the approach is, if for the selected coin, sum - coin >= 0, i.e. coin can be used to get the sum then we have to recursively call the method with the rest of the amount (sum-coin). You also need to ensure that you take the minimum of current count and the result of adding selected coin to count.
count = Math.min(count,  res+1);

Here is the complete Java program with the recursive method.

public class MinCoinSum {
  public static void main(String[] args) {
    int coins[] = {9, 6, 5, 1};
    int sum = 10;
    
    int c = minCoinsNeeded(coins, sum);
    System.out.println("Coins needed- " c);			
  }  
  private static int minCoinsNeeded(int[] coins, int sum) {
    if(sum == 0) {
      return 0;
    }
    int count = Integer.MAX_VALUE;
    int res = 0;
    for(int coin : coins) {
      
      if(sum - coin >= 0) {
        res = minCoinsNeeded(coins, sum-coin);				
        if(res != -1) {
          // if coin needed; that is include 
          // scenario (res+1) otherwise you go with count
          count = Math.min(count,  res+1);	
        }
      }
    }
    return (count == Integer.MAX_VALUE) ? -1 : count;
  }
}

Output

Coins needed- 2

Time and space complexity with this approach

With this approach each recursive call tries all coin denominations. If amount is n and the number of coins is c then the time complexity is O(cn)

Recursion stack depth will be n so, the space complexity is O(n).

2. Using memoization with recursion

With the above recursive method there are many repetitive calls. Memoization improves this by caching results for subproblems.

If the target amount is sum then we may need answers for all amounts from 0 up to sum in this form-

dp[i]= minimum coins required to get amount i

So, we need a 1-D array having length equal to the sum+1. This array is initialized with -1 as initial value to indicate no value is stored yet.

public class MinCoinSum {

  public static void main(String[] args) {
    int coins[] = {9, 6, 5, 1};
    int sum = 101;

    int[] dp = new int[sum+1];
    Arrays.fill(dp, -1);

    int c = minCoinsNeeded(coins, sum, dp);
    System.out.println("Coins needed- " + c);  
  }
  
  private static int minCoinsNeeded(int[] coins, int sum, int[] dp) {
    if(sum == 0) {
      return 0;
    }
    // value already stored, so return that value
    if(dp[sum] != -1) {
      return dp[sum];
    }
    int count = Integer.MAX_VALUE;
    int res = 0;
    // Go through all the coins
    for (int coin : coins) {
      // if current coin can be used to get the final amount
      if(sum - coin >= 0) {
        // recursively find the minimum coins for the remaining amount
        res = minCoinsNeeded(coins, sum - coin, dp);
        
        if(res != -1) {
          count = Math.min(count,  res+1);
        }
      }
    }
    // Store result in array
    dp[sum] = (count == Integer.MAX_VALUE) ? -1 : count;
    return dp[sum];
  }
}

Output

Coins needed- 12

Time and space complexity with this approach

If amount is n and the number of coins is c then the space complexity is O(n X c). As there are n subproblems and c checks for each subproblem.

Space needed is O(n+1) for dp array and O(n) for recursion stack so the overall space complexity is O(n).

3. With tabulation (Bottom-up) approach

With tabulation form, to write logic for minimum number of coins to get the sum, iterative logic is used not recursive which in itself is an optimization. This is also called bottom-up approach as we build solutions for all amounts starting from 0 going up all the way to given sum.

A dp array of length equal to sum+1 is needed as we go through amount 0..sum.

All entries of dp should be initialized to a large number (at least greater than the sum). The value of dp[0] is equal to 0 (zero coins needed for amount 0). The logic for solution is as given below.

  1. Iterate in an outer loop for the coins
  2. In the inner loop, for each amount i, check if using this coin improves the minimum count.
  3. Compare the scenario, if this coin is added which means dp[i – coin]+1 with current dp[i] and take the minimum.
public class MinCoinSum {

  public static void main(String[] args) {
    int coins[] = {9, 6, 5, 1};
    int sum = 101;
    
    int c1 = minNoOfCoins(coins, sum);
    System.out.println("Coins needed- " + c1);  
  }
  
  private static int minNoOfCoins(int[] coins, int sum) {
    
    int[] dp = new int[sum+1];
    // Integer.MAX_VALUE causes problem when 1 is added to it
    //Arrays.fill(dp, Integer.MAX_VALUE);
    Arrays.fill(dp, sum+1);
    dp[0] = 0;
    for(int coin : coins) {
      for(int i = coin; i <= sum; i++) {                  
      dp[i] = Math.min(dp[i], dp[i-coin] + 1);
      }
    }
    return dp[sum] > sum ? -1 : dp[sum];
  }
}

Output

Output
Coins needed- 12

Time and space complexity with this approach

If amount is n and the number of coins is c then, Outer loop runs for each coin i.e. c times. Inner loop runs for each amount up to sum i.e. n times.

Thus, the time complexity is O(n X c).

DP array of size sum + 1 is requires so the space complexity is O(n).

That's all for this topic Coin Change - Min Number of Coines Needed - Java Program. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Programs Page


Related Topics

  1. Longest Increasing Subsequence Java Program
  2. Exponential Search Program in Java
  3. Greatest Common Divisor (GCD) of Two Numbers Java Program
  4. Detect Cycle in an Undirected Graph Using DFS - Java Program
  5. Fibonacci Series Program in Java

You may also like-

  1. Generating Getters And Setters Using Reflection in Java
  2. Producer-Consumer Java Program Using ArrayBlockingQueue
  3. How to Untar a File in Java
  4. How to Read File From The Last Line in Java
  5. How ArrayList Works Internally in Java
  6. throws Keyword in Java Exception Handling
  7. List in Python With Examples
  8. Spring Bean Life Cycle

Saturday, November 29, 2025

Longest Increasing Subsequence Java Program

In this article we'll see how to write a Java program to find the length of the longest increasing subsequence in the given array.

For example-

1. Input: nums = [10, 9, 2, 5, 3, 7, 101, 18]
Output: 4
Explanation: The longest increasing subsequence is [2, 3, 7, 101], therefore the length is 4.

2. Input: nums = [2, 0, 1, 7, 5, 9]
Output: 4
Explanation: The longest increasing subsequence is [0, 1, 7, 9] therefore the length is 4.

3. Input: nums = [4, 4, 4, 4, 4]
Output: 1

The "Longest Increasing Subsequence" problem is a good example of dynamic programming as you can break this problem into smaller overlapping sub-problems and you can also store the result of those subproblems (memoization) to avoid redundant calculations.

Longest Increasing Subsequence Java Program

The program for finding the length of longest increasing subsequence can be written using

  1. Recursion,
  2. You can add memoization with recursion to make it faster this is also called top-down approach in dynamic programming.
  3. You can also use bottom-up approach also known as tabular form. In bottom-up approach you try to solve the sub-problems first and use their solutions to arrive at solutions to bigger sub-problems.

We'll write java programs for all these three approaches here.

1. Using recursion

Let's try to understand what we need to do with an example. Suppose our elements are {9, 10, 11, 12} and i represents current element index and p represents previous element index. If i is pointing at 10 and p at 9 then we'll have to check if(arr[i] > arr[p]) for subsequence.

If condition evaluates to true then we have to do the same comparison for 10 and 11 which means incrementing i by 1 i.e. i=i+1 and assigning previous value of i to p. This is the include scenario and the length of the subsequence increases by one.

Now suppose our elements are {9, 8, 10, 11}. Again, if we check if(arr[i] > arr[p]) for subsequence it evaluates to false for arr[i] = 8 and arr[p] = 9. In this case, you won't change value of p only increment i by 1. That means arr[i]=10 and arr[p]=9. This is excluding scenario where length of the subsequence doesn't increase.

Here is the complete Java program with this approach.

public class LongestIncreasingSubsequence {
  
  public static void main(String[] args) {
     int[] arr = {10, 9, 2, 5, 3, 7, 1, 8};
     
     System.out.println(Arrays.toString(arr));
    
     System.out.println(longestSubsequence(arr, 0, -1));
  }
  
  // Using dynamic programming - recursion
  private static int longestSubsequence(int[] arr, int i, int p) {
    // exit condition
    if(i == arr.length) {
      return 0;
    }
    int max = 0;
    int include = 0;
    
    // don't take scenario- where you just increase the index
    int res = longestSubsequence(arr, i+1, p);
    
    if(p == -1 || arr[i] > arr[p]) {      
      // take scenario- where you increase index and previous index
      include = longestSubsequence(arr, i+1, i)+1;

    }
    max = Math.max(res, include);
    return max;    
  }
}

Output

[10, 9, 2, 5, 3, 7, 1, 8]
4

You call the method with i = 0 and p = -1. Then you have exclude scenario where index of the current element is incremented. Length is not increased as the element is not included in the subsequence.

In the include scenario (arr[i] > arr[p]), both p and i are changed. Length is also increased by 1 (longestSubsequence(arr, i+1, i) + 1) as element is included in the subsequence.

The variable res stores the length of LIS based on p (arr[i] is skipped) whereas variable include stores the length of LIS based on i (arr[i] is included). Since you need the maximum LIS length so you take the max of these two scenarios.

Time and space complexity with this approach

With this approach recursive method explores all subsequences of the array and the number of subsequences of an array of length n is 2n. Therefore the time complexity is O(2n).

Recursion stack depth will be n as we move forward by one index with each method call. So, the space complexity is O(n).

2. Using memoization with recursion.

With the above recursive method there are many repetitive calls with each recursive method for the same i and p value.

What if we use an array to store previous computation values and with each computation we first make a check in the array to see if that computation is already done. That's what we do with memoization approach.

Our method has two parameters i and p so we need a 2D array having row and column length same as the length of input array. This 2D array is initialized with -1 as initial value to indicate no value is stored yet.

public class LongestIncreasingSubsequence {
  
  public static void main(String[] args) {
    int[] arr = {10, 9, 2, 5, 3, 7, 1, 8};
     
    // for memoization
    int[][]dp= new int[arr.length][arr.length];
     
    for(int[] a:dp) {
      Arrays.fill(a, -1);
    }
    System.out.println(Arrays.toString(arr));
    
    System.out.println(longestSubsequenceWithM(arr, 0, -1,dp));
  }
  
  // Using dynamic programming - recursion with Memoization
  private static int longestSubsequenceWithM(int[] arr, int i, int p, int[][] dp) {
    if(i == arr.length) {
      return 0;
      
    }
    int max = 0;
    int include = 0;
    // [p+1] because p can be -1
    // Check if value is already calculated for the passed i and p,
    // if yes then return the same value
    if(dp[i][p+1] != -1) {
      return dp[i][p+1];
    }

    // don't take scenario where you just increase the index
    int res = longestSubsequenceWithM(arr, i+1, p, dp);
    if(p == -1 || arr[i] > arr[p]) {
      // take scenario where you increase index and previous index
      include = longestSubsequenceWithM(arr, i+1, i, dp)+1;            
    }
    max = Math.max(res, include);
    dp[i][p+1] = max;

    return max;
    
  }
}

Output

[10, 9, 2, 5, 3, 7, 1, 8]
4

Time and space complexity with this approach

With memoization, the time complexity becomes O(n2) as each state (i and p) is computed once, rest of the times it is extracted from the dp array.

Space needed is O(n2) for the dp array and O(n) for recursion stack. So the space complexity can be considered as O(n2).

3. With tabulation (Bottom-up) approach.

With this approach for finding the length of the longest increasing subsequence, iterative logic is used. A 1D array of size n is used to store the values where dp[i] stores the length of the longest increasing subsequence ending at index i. Initially, every dp[i] = 1 because each element is a subsequence of length 1 by itself.

There are two loops in the logic, in each iteration of the outer loop (1 <= i < array.length), arr[i] is compared with all the previous elements arr[0] to arr[i-1] in the inner loop, suppose j is used in the inner loop. Then the steps are as given below-

  1. If(arr[i] > arr[j]) – that means arr[i] can extend the increasing subsequence ending at arr[j]
  2. Take the maximum of current known LIS ending at i and what we’d get by appending arr[i] to the LIS ending at j, as the value of dp[i].

Max value in the dp array is the length of the longest increasing subsequence.

public class LongestIncreasingSubsequence {
  public static void main(String[] args) {
    int[] arr = {10, 9, 2, 5, 3, 7, 1, 8};

    System.out.println(Arrays.toString(arr));
    
    System.out.println("lis "+ findLIS(arr));
  }
  
  // Using tabulation
  public static int findLIS(int[] arr) {
    int len = arr.length;
    int[] dp = new int[len];
    Arrays.fill(dp, 1);
    int maxLis = 1;
    for(int i = 1; i < len; i++) {
      for(int j = 0; j < i; j++) {
        if(arr[i] > arr[j]) {          
          dp[i] = Math.max(dp[i], dp[j] + 1);          
        }
      }
    }
    // extract the length of LIS
    for (int length : dp) {
      maxLis = Math.max(maxLis, length);
    }

    return maxLis;
  }
}

Output

[10, 9, 2, 5, 3, 7, 1, 8]
lis 4

That's all for this topic Longest Increasing Subsequence Java Program. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Programs Page


Related Topics

  1. Coin Change - Min Number of Coins Needed - Java Program
  2. How to Find Common Elements Between Two Arrays Java Program
  3. Two Sum - Elements in Array With Given Sum Java Program
  4. Longest Prefix Suffix Java Program

You may also like-

  1. Counting Sort Program in Java
  2. Find The First Repeated Character in a String Java Program
  3. Convert HTML to PDF in Java + Openhtmltopdf and PDFBox
  4. Java Program to Delete File And Directory Recursively
  5. Java Multithreading Interview Questions And Answers
  6. Encapsulation in Python
  7. Signal in Angular With Examples
  8. Spring Profiles With Examples

Wednesday, November 26, 2025

output() Function in Angular With Examples

In this tutorial we'll see what is output() function in Angular and how to use it for facilitating child to parent communication.

output() in Angular

Angular output() function was released in version 17 and it is designed to be used in place of @Output decorator in Angular. This output() function also provides functionality to emit values to parent directives and components.

Angular output() function returns an OutputEmitterRef object which has two methods emit and subscribe which can be used to emit values to parent directives or components.

How to use output()

First thing is to import output from @angular/core.

import { output } from '@angular/core';

Inside your child component declare a variable and initialize it by calling the output() function. You can optionally specify the type of data the output will emit using a generic.

message = output<string>();

Then you can call emit() method on the declared output to send data to the parent component.

this.message.emit('hello');

In the parent component's template you can use event binding to bind to this emit event.

<app-child (message)="receiveMessage($event)"></app-child>

output() in Angular examples

1. In the first example we'll have a child component where we take input from the user and that input value is then send to the parent component using output().

child.component.ts

import { Component, output } from "@angular/core";

@Component({
    selector:'app-child',
    templateUrl: './child.component.html',
    standalone:false
})
export class ChildComponent{
  message = output<string>();

  sendMessage(value: string){
    this.message.emit(value);
  }
}

child.component.html

<div>
  <input type="text" id="msgInput" #msgInput/>
  <button (click)="sendMessage(msgInput.value)">Submit</button>
</div>

On the click of the button, value of the input which is referenced using a template reference variable (#msgInput) is passed to the bound method.

parent.component.ts

import { Component } from "@angular/core";

@Component({
  selector:'app-parent',
  templateUrl: './parent.component.html',
  standalone:false
})
export class ParentComponent{
  message:string='';

  recvMessage(msg: string){
    this.message = msg;
  }
}

Value which is received from the child component is assigned to the message variable.

parent.component.html

<app-child (message)="recvMessage($event)"></app-child>
{{message}}

2. Let's say we have an array of Product objects and we want to use a presentational component (a child component) to display product data, where product data is passed from a container component (parent component). Container component also has methods to increment or decrement the product quantity, event handling for incrementing or decrementing is done through the output() function.

This example shows how to use signals, input() and output() together to write Angular code.

Model Class (product.model.ts)
export class Product{
  id: number;
  name: string;
  price: number;
  quantity: number;

  constructor(id: number, name: string, price: number, quantity: number){
    this.id = id;
    this.name = name;
    this.price = price;
    this.quantity = quantity;
  }
}

productssignal.component.ts (parent component)

export class ProductsSignalComponent{
  products = signal<Product[]>([
    new Product(1, 'Laptop', 1000, 1),
    new Product(2, 'RAM', 30, 5),
    new Product(3, 'Mouse', 15, 4),
    new Product(4, 'Headphones', 200, 3),
  ]);
  grandTotal = computed(() => {
    return this.products().reduce((sum, product) => {
      const productTotal = product.price * product.quantity;
      return sum + productTotal;
    }, 0);
  });
    
  decrementQuantity(index: number){
    this.products.update(products => {
      if(products[index].quantity > 0){
        products[index].quantity--;
      }
          
      return [...products];
    });
  }

  incrementQuantity(index: number){
    this.products.update(products => {
      products[index].quantity++;                            
      return [...products];
    });
  }
}

productssignal.component.html

<app-signalproduct [productList]="products()" 
  [grandTotal]="grandTotal()"
  (decrement)="decrementQuantity($event)" 
  (increment)="incrementQuantity($event)"/>

Here you can see how properties in child component, which are defined as input(), are bound using property binding and properties, which are defined as output(), are bound using event binding.

productsignal.component.ts (Child Component)

import { Component, input, output } from "@angular/core";
import { Product } from "../models/product.model";

@Component({
  selector:'app-signalproduct',
  templateUrl: './productsignal.component.html',
  standalone:false,

})
export class ProductSignalComponent{
  productList = input.required<Product[]>();
  grandTotal = input.required<number>();
  decrement = output<number>();
  increment = output<number>();

  decrementQ(index:number){
    this.decrement.emit(index);
  }

  incrementQ(index:number){
    this.increment.emit(index);
  }
}

In the component there are two properties defined as input() to get product data and grand total from the parent component. There are also two properties to send index of the product element whose increment or decrement button is clicked. How these properties are bound to the parent component can be seen in the productssignal.component.html

productsignal.component.html

<h1>Product List </h1>

<table border="1">
  <thead>
    <tr>
      <th>ID</th>
      <th>Name</th>
      <th>Price</th>
      <th>Quantity</th>
      <th>Total Price</th>
    </tr>
  </thead>
  <tbody>
    @for(product of productList(); track product.id; let i = $index){
        <tr>
            <td>{{ product.id }}</td>
            <td>{{ product.name }}</td>
            <td>{{ product.price }}</td>
            <td><button (click)="decrementQ(i)">-</button>{{ product.quantity}}<button (click)="incrementQ(i)">+</button></td>
            <td>{{ product.price * product.quantity}}</td>
        </tr>
    }
  </tbody>
  <tfoot>
    <tr>
      <td colspan="4"><strong>Grand Total:</strong></td>
      <td><strong>{{ grandTotal() | currency:'USD' }}</strong></td>
    </tr>
  </tfoot>
</table>
output() Function in Angular

That's all for this topic output() Function in Angular With Examples. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Angular Tutorial Page


Related Topics

  1. input() Function in Angular With Examples
  2. Signal in Angular With Examples
  3. @for in Angular With Examples
  4. Angular @Component Decorator
  5. Angular Custom Event Binding Using @Output Decorator

You may also like-

  1. Angular HttpClient - Set Response Type as Text
  2. Angular Template-Driven Form Validation Example
  3. Angular ngClass Directive With Examples
  4. Passing Query Parameters in Angular Routing
  5. AtomicInteger in Java With Examples
  6. Z Algorithm For Pattern Search - Java Program
  7. Dictionary in Python With Examples
  8. registerShutdownHook() Method in Spring Framework

Tuesday, November 25, 2025

input() Function in Angular With Examples

In this tutorial we'll see what is input() function in Angular and how to use it for facilitating parent-child communication.

input() in Angular

Angular input() function was released in version 17 as a part of Angular's signal based API. This input() function provides another way than the @Input decorator for parent-child communication.

Angular input() function returns a signal based property that automatically reacts to the changes from the parent. That makes the component data flow more streamlined and reactive.

How to define input

First thing is to import input from @angular/core.

import {input} from '@angular/core';

1. input() as optional

You can define input as optional which is the default option.

name = input<string>();

You can also define it with a default value. This default value is used if no value is passed from the parent.

name = input<string>(‘TestUser’);

2. Required inputs

You can also define input as a required value. Using input.required() enforces that a value must be provided when the component is used, and Angular will throw a build-time error if it's missing.

name=input.required<string>()

input() in Angular examples

Let's say we have an array of User objects and we want to use a presentational component (a child component) to display user data, where user data is passed from a container component (parent component).

User Model class

export class User {
  id: number;
  firstName : string;
  lastName : string;
  age : number;
  constructor(id:number, firstName: string, lastName: string, age: number) {
    this.id = id;
    this.firstName = firstName;
    this.lastName = lastName;
    this.age = age;
  }
}

users.component.ts (Parent Component)

import { Component } from "@angular/core";
import { User } from "../models/user.model";

@Component({
  selector:'app-users',
  templateUrl: './users.component.html',
  standalone:false
})
export class UsersComponent{    
  users: User[] = [
    new User(1, 'Ram', 'Tiwari', 34),
    new User(2, 'Agatha', 'Christie', 23),
    new User(3, 'Mahesh', 'Agastya', 45),
  ]
}

users.component.html

<ul>
  @for(user of users; track user.id){
    <li>
      <app-user [user]="user"></app-user>
    </li>
  }
</ul>

user.component.ts (Child component)

import { Component, computed, input } from "@angular/core";
import { User } from "../models/user.model";

@Component({
  selector:'app-user',
  templateUrl: './user.component.html',
  standalone:false
})
export class UserComponent{ 
  user = input.required<User>();
}

As you can see user is defined as input.required here, so parent must pass the value for user.

user.component.html

{{user().firstName}} {{user().lastName}} {{user().age}}

Inputs are signals, so user is a signal that is why it has to be accessed with round brackets i.e. user().

Now, suppose you need to display full name. Since inputs are signal so you can create a computed signal to compute the full name by concatenating first name and last name.

user.component.ts

import { Component, computed, input } from "@angular/core";
import { User } from "../models/user.model";

@Component({
  selector:'app-user',
  templateUrl: './user.component.html',
  standalone:false
})
export class UserComponent{ 
  user = input.required<User>();
  fullName = computed(() => {
    const u = this.user();
    return u.firstName + " " + u.lastName
  });
}

user.component.html

{{fullName()}}

Configuring inputs

The input function accepts a config object as a second parameter that lets you change the way that input works.

Input transforms

You can specify a transform function to change the value of an input when it's set by Angular.

For example, if you are getting a string value and you want to trim the input value then you can provide a transform function to do it.

@Component({
  selector: 'app-username',
  /*...*/
})
export class UserComponent {
  name = input('', {transform: trimString});
}
function trimString(value: string | undefined): string {
  return value?.trim() ?? '';
}

Input aliases

You can specify the alias option to change the name of an input in templates.

@Component({
    selector:'app-user',
    templateUrl: './user.component.html',
    standalone:false
})
export class UserComponent{ 
    user = input.required<User>({alias:'userdata'});
}

Here userdata alias is given to the user input. Then in the call to this component

<app-user [userdata]="user"></app-user>

That's all for this topic input() Function in Angular With Examples. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Angular Tutorial Page


Related Topics

  1. @for in Angular With Examples
  2. @if in Angular With Examples
  3. Angular @Component Decorator
  4. What is Client Side Routing in Angular
  5. Angular Application Bootstrap Process

You may also like-

  1. Angular ngFor Directive With Examples
  2. Angular Disable Button Example
  3. Async Pipe in Angular With Examples
  4. Angular Reactive Form Validation Example
  5. intern() Method in Java String
  6. Java Program - Minimum Spanning Tree - Prim's Algorithm
  7. Method Overloading in Python
  8. Spring JdbcTemplate With ResultSetExtractor Example

Monday, November 24, 2025

Signal in Angular With Examples

In this tutorial we'll see what is signal in Angular and how it is a move towards reactive state management by Angular framework.

Signal in Angular

Angular Signals were officially released in Angular 17 and they provide fine-grained control over the changes in the component. Angular Signals optimize DOM changes by providing a fine-grained, reactive system for updating the UI. When a signal's value change, only those components, which are using that signal value, are notified, that allows Angular to update only the affected sections of the DOM making the process of reloading the component faster. This is an optimization over the full change detection cycle where the full component tree is scanned, starting from the root component and moving downwards.

How are signals defined

A signal is a wrapper around a value and it manages its state. When that value changes all the dependent components are notified. Signals can contain any value, from primitives to complex objects.

For example-

const count = signal(0);

You can create a signal by calling the signal function with the signal's initial value.

How to Read a Signal

You can read a value of the signal by calling the signal with parenthesis.

For example- count()

This calls the signal's getter function.

Types of signals in Angular

Angular signals can be of two types-

  1. Writable signals
  2. Read-only signals

Writable signals

You can create a writable signal by calling the signal function with the signal's initial value. This value can be modified later by using set() or update() function.

If you want to provide a new value to a writable signal, you can set it directly using .set()

count.set(5);

If you want to compute a new value using the previous one, then .update() is a better option.

// increment previous count value by 1
count.update(pv => pv + 1)

Read-only signals

Read-only or computed signals derive their value from other signals. These signals are defined using the computed function, you have to specify the derived value logic with in the computed function.

As example, if there is a Product object with properties as id, name, price and quantity and you want to calculate the total price based on the quantity and price of the product.

productSignal = signal<Product>(id:1, name:'Laptop', price:1000, quantity:5));
// Readable signal
totalPrice = computed(() => {
        const product = this.productSignal();
        return product.price * product.quantity;
});

Here totalPrice signal depends on the price and quantity of the product signal. Whenever the price or quantity updates, Angular knows that totalPrice needs to be updated as well.

As the name suggests, you cannot directly assign values to a read-only signal. Trying to do something like this-

totalPrice.set(5000);

results in a compilation error.

Note that read-only signals are both lazily evaluated and memoized (cached). The logic you have written to derive the value of a computed signal does not run to calculate its value until the first time you read that value.

The calculated value is then cached and the same value is returned when needed without recalculating. If you change any value which is used to calculate the read-only signal value then Angular knows that read-only signal's cached value is no longer valid and it calculates the new value when needed the next time.

Angular Signals example

1. In this simple example there is a count signal with initial value as 0. In the template there is a button, click of that button triggers an event to increment the count.

signaldemo.component.ts

import { Component, signal } from "@angular/core";

@Component({
    selector:'app-signaldemo',
    templateUrl: './signaldemo.component.html',
    standalone:false
})
export class SignalDemoComponent{
    count = signal(0);

    increment(){
        this.count.update(count => count+1);
        console.log(this.count);
    }
}

As you can see in the increment() method, count signal is updated.

src\app\signaldemo.component.html
<div>{{count()}}</div>

<button (click)="increment()">Increment</button>

2. This example demonstrates the use of read-only signal. There is a Product object with properties as id, name, price and quantity and you want to calculate the total price based on the quantity and price of the product.

models\product.model.ts

export class Product{
    id: number;
    name: string;
    price: number;
    quantity: number;

    constructor(id: number, name: string, price: number, quantity: number){
        this.id = id;
        this.name = name;
        this.price = price;
        this.quantity = quantity;
    }
}

Above class is used to create Product objects.

singleproduct.component.ts

import { Component, computed, signal } from "@angular/core";
import { Product } from "../models/product.model";

@Component({
  selector:'app-productSingle',
  templateUrl: './singleproduct.component.html',
  standalone:false
})
export class SingleProductComponent{
  productSignal = signal<Product>(new Product(1, 'Laptop', 1000, 1));

  totalPrice = computed(() => {
    const product = this.productSignal();
    return product.price * product.quantity;
  });
  decrementQuantity():void{
    this.productSignal.update((product) => {
      if(product.quantity > 0){
        return {...product, quantity:product.quantity-1};
          
      }else{
        return {...product};
      }
    });
  }

  incrementQuantity(){
    console.log('increment')
    this.productSignal.update((product) => (
        {...product, quantity:product.quantity+1}
    ));
  }

}

Points to note here-

  1. Product object is created as a signal.
  2. There are two methods to decrement or increment the quantity. In both of these methods signal value of the product is updated by decrementing or incrementing the product.quantity.
  3. There is a computed signal, totalPrice whose value is derived by multiplying the product.price and product.quantity.

singleproduct.component.html

<h1>Product List</h1>

<table border="1">
  <thead>
    <tr>
      <th>ID</th>
      <th>Name</th>
      <th>Price</th>
      <th>Quantity</th>
      <th>Total Price</th>
    </tr>
  </thead>
  <tbody>
    <tr>
        <td>{{ productSignal().id }}</td>
        <td>{{ productSignal().name }}</td>
        <td>{{ productSignal().price }}</td>
        <td><button (click)="decrementQuantity()">-</button>{{ productSignal().quantity}}<button (click)="incrementQuantity()">+</button></td>
        <td>{{totalPrice()}}</td>
    </tr>
  </tbody>
  </table>

3. This example builds on the second example by having an array of Product objects and having a computed signal for grand total.

productsignal.component.ts

import { Component, computed, signal } from "@angular/core";
import { Product } from "../models/product.model";

@Component({
  selector:'app-signalproduct',
  templateUrl: './productsignal.component.html',
  standalone:false
})
export class ProductSignalComponent{
  products = signal<Product[]>([
    new Product(1, 'Laptop', 1000, 1),
    new Product(2, 'RAM', 30, 5),
    new Product(3, 'Mouse', 15, 4),
    new Product(4, 'Headphones', 200, 3),
  ]);

  grandTotal = computed(() => {
    return this.products().reduce((sum, product) => {
      const productTotal = product.price * product.quantity;
      return sum + productTotal;
    }, 0);
  });
    
  decrementQuantity(index: number){
    this.products.update(products => {
      if(products[index].quantity > 0){
        products[index].quantity--;
      }
          
      return [...products];
    });
  }

  incrementQuantity(index: number){
    this.products.update(products => {
      products[index].quantity++;                            
      return [...products];
    });
  }
}

Points to note here-

  1. Here we have an array of Product objects.
  2. For incrementing or decrementing quantity, index of the array is passed to the method as parameter. Using that quantity is incremented or decremented for that specific product.
  3. Since signals in Angular use reference equality to decide if something has changed. It is important to keep state of the object or array as immutable. That is why spread operator is used to create a new array object.

productsignal.component.html

<h1>Product List </h1>

<table border="1">
  <thead>
    <tr>
      <th>ID</th>
      <th>Name</th>
      <th>Price</th>
      <th>Quantity</th>
      <th>Total Price</th>
    </tr>
  </thead>
  <tbody>
    @for(product of products(); track product.id; let i = $index){
        <tr>
            <td>{{ product.id }}</td>
            <td>{{ product.name }}</td>
            <td>{{ product.price }}</td>
            <td><button (click)="decrementQuantity(i)">-</button>{{ product.quantity}}<button (click)="incrementQuantity(i)">+</button></td>
            <td>{{ product.price * product.quantity}}</td>
        </tr>
    }
  </tbody>
  <tfoot>
    <tr>
      <td colspan="4"><strong>Grand Total:</strong></td>
      <td><strong>{{ grandTotal() | currency:'USD' }}</strong></td>
    </tr>
  </tfoot>
  </table>
Angular Signal Example

That's all for this topic Signal in Angular With Examples. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Angular Tutorial Page


Related Topics

  1. input() Function in Angular With Examples
  2. @for in Angular With Examples
  3. @if in Angular With Examples
  4. Angular @Component Decorator
  5. What is Client Side Routing in Angular

You may also like-

  1. Angular ngFor Directive With Examples
  2. Angular Disable Button Example
  3. Async Pipe in Angular With Examples
  4. Angular Reactive Form Validation Example
  5. intern() Method in Java String
  6. Java Program - Minimum Spanning Tree - Prim's Algorithm
  7. Method Overloading in Python
  8. Spring JdbcTemplate With ResultSetExtractor Example