CodeByAkram: Interview Questions
Showing posts with label Interview Questions. Show all posts
Showing posts with label Interview Questions. Show all posts

Merge sort in Java

Related questions: Sort Linked List using Merge Sort, Given a Linked list, Sort it using Merge Sort Algorithm.

Merge sort is preferred algorithm for sorting a linked list, lets see why,
The way linked list is structured which doesn't allow random access makes some other algorithms like Quicksort perform poorly, So Merge sort is often preferred algorithm for sorting linked list.

Lets understand what is the input and the expected output.
Algorithm (We will use Merge Sort for sorting Linked list.)
For sorting Linked list, we can use any algorithm but the most suitable algorithm is Merge Sort.

Why is merge sort preferred over quick sort for sorting linked lists?

As Singly Linked list can be accessed in only one direction and cannot be accessed randomly, Quick sort will not be well suitable here.

Quick sort requires access to elements in both direction for swapping and doing such operation in Linked list is not as easy as working with Arrays.
Starting from the end and moving backward is usually expensive operation in Singly linked list.
So Quick sort is well suited for arrays and not linked list.

Merge sort is a divide and conquer algorithm in which need of Random access to elements is less.
So Merge Sort can be used for sorting Linked list.


How Merge Sort works

  1. Merge Sort works by breaking the linked list(or Array) into 2 equal parts say Left half and Right half.
  2. Again break 2 list that we got in Step 1 in two equal parts each.  
  3. Repeat above steps until only 1 element remains in Linked list (or Array) because list with only 1 element is always sorted. 
  4. So in each step we are breaking the list in Left half and Right half.  
  5. When complete list is divided and contains only Single element in Left and Right half each, Start comparing and sorting each Left and Right half, So that portion of Linked list will be sorted.
  6. Repeat Step 5 for all the remaining Left and Right half and complete linked list will be sorted.
It works on divide and conquer technique. Time complexity is O(N log N).
Lets understand with the help of below example.
 
Sorting Linked list using Merge sort in Java. (Recursive Approach)


package linkedlist.singly;
 
public class SortLinkedList {
 
 Node startNode;
  
 public static void main(String[] args) {
  new SortLinkedList();
 }
 
 public SortLinkedList() {
  Node node1 = new Node(10);
  Node node2 = new Node(1);
  Node node3 = new Node(-2);
  Node node4 = new Node(8);
  Node node5 = new Node(9);
  Node node6 = new Node(10);
  Node node7 = new Node(1);
 
  node1.setNext(node2);
  node2.setNext(node3);
  node3.setNext(node4);
  node4.setNext(node5);
  node5.setNext(node6);
  node6.setNext(node7);
 
  startNode = node1;
   
  Node sortedStartNode = mergeSortLinkList(startNode);
  printLinkList(sortedStartNode);
 }
 
 private Node mergeSortLinkList(Node startNode){
   
  //Break the list until list is null or only 1 element is present in List.
  if(startNode==null || startNode.getNext()==null){
   return startNode;
  }
 
  //Break the linklist into 2 list.
  //Finding Middle node and then breaking the Linled list in 2 parts.
  //Now 2 list are, 1st list from start to middle and 2nd list from middle+1 to last.
   
  Node middle = getMiddle(startNode);
  Node nextOfMiddle = middle.getNext();
  middle.setNext(null);
 
  //Again breaking the List until there is only 1 element in each list.
  Node left = mergeSortLinkList(startNode);
  Node right = mergeSortLinkList(nextOfMiddle);
 
  //Once complete list is divided and contains only single element, 
  //Start merging left and right half by sorting them and passing Sorted list further. 
  Node sortedList = mergeTwoListRecursive(left, right);
   
  return sortedList;
 }
 
 //Recursive Approach for Merging Two Sorted List
 private Node mergeTwoListRecursive(Node leftStart, Node rightStart){
  if(leftStart==null)
   return rightStart;
   
  if(rightStart==null)
   return leftStart;
 
  Node temp=null;
   
  if(leftStart.getData() < rightStart.getData()){
   temp=leftStart;
   temp.setNext(mergeTwoListRecursive(leftStart.getNext(), rightStart));
  }else{
   temp=rightStart;
   temp.setNext(mergeTwoListRecursive(leftStart, rightStart.getNext()));
  }
  return temp;
 }
 
 private Node getMiddle(Node startNode) {
  if(startNode==null){
   return startNode;
  }
 
  Node pointer1=startNode;
  Node pointer2=startNode;
   
  while(pointer2!=null && pointer2.getNext()!=null && pointer2.getNext().getNext()!=null){
   pointer1 = pointer1.getNext();
   pointer2 = pointer2.getNext().getNext();
 
  }
  return pointer1;
 }
 
 private void printLinkList(Node startNode) {
  Node temp = startNode;
  while(temp!=null){
   System.out.print(temp.getData() + " ");
   temp = temp.getNext();
  }
 }
  
}
Sorting Linked list using Merge sort in Java. (Iterative Approach)

package linkedlist.singly;
 
public class SortLinkedList {
 
 Node startNode;
 
 public static void main(String[] args) {
  new SortLinkedList();
 }
 
 public SortLinkedList() {
  Node node1 = new Node(10);
  Node node2 = new Node(1);
  Node node3 = new Node(-2);
  Node node4 = new Node(8);
  Node node5 = new Node(9);
  Node node6 = new Node(10);
  Node node7 = new Node(1);
 
  node1.setNext(node2);
  node2.setNext(node3);
  node3.setNext(node4);
  node4.setNext(node5);
  node5.setNext(node6);
  node6.setNext(node7);
 
  startNode = node1;
 
  Node sortedStartNode = mergeSortLinkList(startNode);
  printLinkList(sortedStartNode);
 }
 
 private Node mergeSortLinkList(Node startNode){
 
  //Break the list until list is null or only 1 element is present in List.
  if(startNode==null || startNode.getNext()==null){
   return startNode;
  }
 
  //Break the linklist into 2 list.
  //Finding Middle node and then breaking the Linled list in 2 parts.
  //Now 2 list are, 1st list from start to middle and 2nd list from middle+1 to last.
 
  Node middle = getMiddle(startNode);
  Node nextOfMiddle = middle.getNext();
  middle.setNext(null);
 
  //Again breaking the List until there is only 1 element in each list.
  Node left = mergeSortLinkList(startNode);
  Node right = mergeSortLinkList(nextOfMiddle);
 
  //Once complete list is divided and contains only single element, 
  //Start merging left and right half by sorting them and passing Sorted list further. 
  Node sortedList = mergeTwoListIterative(left, right);
 
  return sortedList;
 }
 
 //Iterative Approach for Merging Two Sorted List
 private Node mergeTwoListIterative(Node leftStart, Node rightStart) {
 
  Node merged=null;
  Node temp=null;
 
  //To keep track of last element, so that we don't need to iterate for adding the element at last of 
  //list when either LeftStart or rightStart is NULL.
  Node lastAddedNode = null;
 
  while(leftStart!=null && rightStart!=null){
 
   if(leftStart.getData()>rightStart.getData()){
    temp = new Node(rightStart.getData());
    rightStart=rightStart.getNext();
 
   }else{
    temp = new Node(leftStart.getData());
    leftStart=leftStart.getNext();
   }
 
   if(merged==null){
    merged=temp;
   }else{
    lastAddedNode.setNext(temp);     
   }
   lastAddedNode=temp;
  }
 
  if(leftStart!=null){
   lastAddedNode.setNext(leftStart);
  }else{
   lastAddedNode.setNext(rightStart);
  }
   
  return merged;
 }
 
 private Node getMiddle(Node startNode) {
  if(startNode==null){
   return startNode;
  }
 
  Node pointer1=startNode;
  Node pointer2=startNode;
 
  while(pointer2!=null && pointer2.getNext()!=null && pointer2.getNext().getNext()!=null){
   pointer1 = pointer1.getNext();
   pointer2 = pointer2.getNext().getNext();
 
  }
  return pointer1;
 }
 
 private void printLinkList(Node startNode) {
  Node temp = startNode;
  while(temp!=null){
   System.out.print(temp.getData() + " ");
   temp = temp.getNext();
  }
 }
 
}

Insertion Sort in Java

Given a array of integers, Sort it using Insertion sort.
Lets understand what is the input and the expected output.

Example
Assume 5 persons of different heights are visiting at your office each at 5 minutes interval and you need to make them stand according to their heights(smaller to higher). How you will do?

Below is the sequence in which person is going to visit you,

You need to arrange above persons based on their height.
First "A" will visit and that is the only person present, so just tell him to stand and you don't need to take any decision.
Second "B" will visit, so now you have to compare "B" height with "A" height, which is smaller, so shift "A" one step back and move "B" one step ahead.
Now, you have arranged 2 persons properly.
Now "C" entered in office, so you have to find proper position for "C" to stand.
First you will compare "C" height with "A", which is smaller so "A" need to be shifted one step back and "C" need to be shifted one step in front.
Now, compare "C" height with "B", which is higher than "B", So stop here because you have found proper position of "C" to stand.
Now, you have arranged 3 persons properly.
Now "E" entered in office, so you have to find proper position for "E" to stand.
First you will compare "E" height with "D", which is smaller so "D" need to be shifted one step back and "E" need to be shifted one step in front.
Now compare "E" height with "A", which is smaller so "A" need to be shifted one step back and "E" need to be shifted one step in front.
Now compare "E" height with "C", which is smaller so "C" need to be shifted one step back and "E" need to be shifted one step in front.
Now, compare "E" height with "B", which is higher than "B", So stop here because we have found proper position of "E" to stand and all the person ahead of B will be smaller than "B", so no need to check further.
Same logic we will use in Insertion sort.
Algorithm
Insertion Sort is very basic and easy sorting algorithm to understand and implement.
Insertion sort works by shifting and putting element at its correct position in array.
 Lets see how it works:

Insertion sort start's sorting an array by picking 1st element of array.
(We begin by assuming that a array with one item (position 0) is already sorted.)
So now we have one sorted elements set.

Now, we will pick 2nd element of array and compare it with sorted elements set one by one until we find correct position of 2nd element in sorted set.
Elements which are higher than 2nd element are shifted one step back to make space for 2nd element.
After putting 2nd element at its correct position, we have 2 elements in our sorted set.

Now, we will pick 3rd element of array and compare it with sorted elements set one by one until we find correct position of 3rd element in sorted set.
Elements which are higher than 3rd element are shifted one step back to make space for 3rd element.
After putting 3rd element at its correct position, we have 3 elements in our sorted set.

Repeat the process until all elements are sorted. 
Complexity
1. The insertion sort, unlike the other sorts, passes through the array only once. 
2. The insertion sort splits an array into two sub-arrays,
    First sub-array on left side is always sorted and increases in size as the sort continues.
    Second sub-array is unsorted, contains all the elements yet to be inserted into the first sub-array,
    and decreases in size as the sort continues.

3. Insertion sort is efficient for (quite) small data sets.
4. It is more efficient than selection sort or bubble sort.
5. Insertion sort is very efficient for arrays which is nearly(almost) sorted and it sorts nearly sorted
    array in time complexity of O(N).
    (For sorting an array containing elements in descending order to ascending order, insertion sort
    will give poor performance and complexity will be O(N^2))

6. It is Stable sort; i.e., does not change the relative order of elements with equal keys.
7. It is In-place sort; i.e., only requires a constant amount O(1) of additional memory space
8. It can sort elements as it receives it and no need of complete data initially before start sorting.
    (Online).
Java Program for Insertion Sort

package sorting;
 
public class InsertionSort {
 public static void main(String[] args) {
  new InsertionSort();
 }
 
 public InsertionSort() {
  int[] arr=new int[]{1,9,4,10,0};
 
  System.out.println("Before Sorting...");
  printArray(arr);
   
  insertionSort(arr);
   
  System.out.println("\nAfter Sorting...");
  printArray(arr);
 }
 
 private void insertionSort(int arr[]){
  if(arr==null || arr.length<2){
   return;
  }
 
  for (int i = 1; i < arr.length; i++) {
   int temp = arr[i];
    
   // Comparison starts from one step back of element on which we are working that is i.
   int j=i-1; 
    
   //Compare elements till we not found element higher than temp or all element are compared.
   while( j >= 0 && arr[j] > temp){
    arr[j+1] = arr[j];
    j--;
   }
   arr[j+1]=temp;   
  }
 }
 
 private void printArray(int arr[]){
  for (int i = 0; i < arr.length; i++) {
   System.out.print(arr[i] + " ");
  }
 }
  
}

How To deploy Spring Boot application on Tomcat?

How To deploy Spring Boot application on existing Tomcat?

Related Questions:- Deploy a Spring Boot WAR into a Tomcat Server, Spring Boot – Deploy WAR file to Tomcat

spring boot tomcat codybyakram


Spring boot is a framework that allow you to set up production ready setup of spring application and also Tomcat is one of the most popular server used for Java. By default spring boot application build a standalone application that can contains the Tomcat. But if you have your existing Tomcat and you want to deploy your spring boot application on that server than you need to follow the below steps.

Add the below dependency in pom.xml

               <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>

And change the packaging to war or just add the below code in pon.xml.

             <packaging>war</packaging>

Finally, we initialize the Servlet context required by Tomcat by implementing the SpringBootServletInitializer interface and override the configure method:

@SpringBootApplication
public class Application extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);

public static void main(String[] args) {
SpringApplication.run(Application.class, args);

}
}

Now build war file using below maven command,
      
      mvn clean package

How to use regular expressions with String methods in Java?


How to use regular expressions with String methods in Java?
regular expressions codebyakram

Strings in Java have built-in support for regular expressions. 
Strings have 4 built-in methods for regular expressions, i.e., the matches()split())replaceFirst() and replaceAll() methods.

Method
Description
s.split("regex")
Creates an array with substrings of s divided at occurrence of "regex""regex" is not included in the result.
s.replaceFirst("regex"), "replacement"
Replaces first occurrence of "regex" with replacement.
s.matches("regex")
Evaluates if "regex" matches s. Returns only true if the WHOLE string can be matched.
s.replaceAll("regex"), "replacement"
Replaces all occurrences of "regex" with replacement.

Now lets see the implementation of regex in Java String.

package com.codebyakram.regex;
public class RegexTest {
    public static final String DATA = "This is my small example "
            + "string which I'm going to " + "use for pattern matching.";

    public static void main(String[] args) {
        System.out.println(DATA.matches("\\w.*"));
        String[] splitString = (DATA.split("\\s+"));
        System.out.println(splitString.length);// should be 14
        for (String string : splitString) {
            System.out.println(string);
        }
        // replace all whitespace with tabs
        System.out.println(DATA.replaceAll("\\s+", "\t"));
    }
}
Examples
  Now let’s see another example for regex in Java.


package com.codebyakram.regex;;

public class StringMatcher {
    // returns true if the string matches exactly "true"
    public boolean isTrue(String s){
        return s.matches("true");
    }
    // returns true if the string matches exactly "true" or "True"
    public boolean isTrueVersion2(String s){
        return s.matches("[tT]rue");
    }

    // returns true if the string matches exactly "true" or "True"
    // or "yes" or "Yes"
    public boolean isTrueOrYes(String s){
        return s.matches("[tT]rue|[yY]es");
    }

    // returns true if the string contains exactly "true"
    public boolean containsTrue(String s){
        return s.matches(".*true.*");
    }


    // returns true if the string contains of three letters
    public boolean isThreeLetters(String s){
        return s.matches("[a-zA-Z]{3}");
        // simpler from for
//      return s.matches("[a-Z][a-Z][a-Z]");
    }



    // returns true if the string does not have a number at the beginning
    public boolean isNoNumberAtBeginning(String s){
        return s.matches("^[^\\d].*");
    }
    // returns true if the string contains a arbitrary number of characters except b
    public boolean isIntersection(String s){
        return s.matches("([\\w&&[^b]])*");
    }
    // returns true if the string contains a number less than 300
    public boolean isLessThenThreeHundred(String s){
        return s.matches("[^0-9]*[12]?[0-9]{1,2}[^0-9]*");
    }

}

What are the rules of writing regular expressions in Java?

What are the rules of writing regular expressions?


There are some rules for writing a regular expression or regex in java. Lets discuss about those rule. But first have a look on  What are regular expressions or regex?

Common matching symbols that used in regex

Regular Expression
Description
.
Matches any character
^regex
Finds regex that must match at the beginning of the line.
regex$
Finds regex that must match at the end of the line.
[abc]
Set definition, can match the letter a or b or c.
[abc][vz]
Set definition, can match a or b or c followed by either v or z.
[^abc]
When a caret appears as the first character inside square brackets, it negates the pattern. This pattern matches any character except a or b or c.
[a-d1-7]
Ranges: matches a letter between a and d and figures from 1 to 7, but not d1.
X|Z
Finds X or Z.
XZ
Finds X directly followed by Z.
$
Checks if a line end follows.

 

 Meta characters

There are some pre-defined meta characters that are used to make certain common patterns easier to use. Let’s have a look on these characters.
Regular Expression
Description
\d
Any digit, short for [0-9]
\D
A non-digit, short for [^0-9]
\s
A whitespace character, short for [ \t\n\x0b\r\f]
\S
A non-whitespace character, short for
\w
A word character, short for [a-zA-Z_0-9]
\W
A non-word character [^\w]
\S+
Several non-whitespace characters
\b
Matches a word boundary where a word character is [a-zA-Z0-9_]


Quantifier

Quantifier defines how often an element can occur. The symbols ?, *, + and {} are qualifiers.

Regular Expression
Description
Examples
*
Occurs zero or more times, is short for {0,}
X* finds no or several letter X, <sbr /> .* finds any character sequence
+
Occurs one or more times, is short for {1,}
X+- Finds one or several letter X
?
Occurs no or one times, ? is short for {0,1}.
X? finds no or exactly one letter X
{X}
Occurs X number of times, {} describes the order of the preceding liberal
\d{3} searches for three digits, .{10} for any character sequence of length 10.
{X,Y}
Occurs between X and Y times,
\d{1,4} means \d must occur at least once and at a maximum of four.
*?
? after a quantifier makes it a reluctant quantifier. It tries to find the smallest match. This makes the regular expression stop at the first match.


Grouping and back reference
We can group parts of regular expression. In pattern we group elements with round brackets, e.g., (). This allows us to assign a repetition operator to a complete group.
In addition, these groups also create a back reference to the part of the regular expression. This captures the group. A back reference stores the part of the String which matched the group. This allows you to use this part in the replacement.
Via the $ you can refer to a group. $1 is the first group, $2 the second, etc.
Let’s, for example, assume we want to replace all whitespace between a letter followed by a point or a comma. This would involve that the point or the comma is part of the pattern. Still it should be included in the result.
// Removes whitespace between a word character and . or ,String pattern = "(\\w)(\\s+)([\\.,])";System.out.println(DATA.replaceAll(pattern, "$1$3"));

This example extracts the text between a title tag.
// Extract the text between the two title elementspattern = "(?i)(<title.*?>)(.+?)()";String updated = EXAMPLE_TEST.replaceAll(pattern, "$2");
Negative look ahead
It provides the possibility to exclude a pattern. With this we can say that a string should not be followed by another string.
Negative look ahead are defined via (?!pattern). For example, the following will match "a" if "a" is not followed by "b".
a(?!b)

Specifying modes inside the regular expression
We can add the mode modifiers to the start of the regex. To specify multiple modes, simply put them together as in (?ismx).
·       (?i) makes the regex case insensitive.
·       (?s) for "single line mode" makes the dot match all characters, including line breaks.
·       (?m) for "multi-line mode" makes the caret and dollar match at the start and end of each line in the subject string.
 Backslashes in Java
The backslash \ is an escape character in Java Strings. That means backslash has a predefined meaning in Java. You have to use double backslash \\ to define a single backslash. If you want to define \w, then you must be using \\w in your regex. If you want to use backslash as a literal, you have to type \\\\ as \ is also an escape character in regular expressions.