Saturday, September 18, 2021

Flood Fill 4-directional using Java

How it works?
Flood-fill (node):
  1. Set Q to the empty queue or stack.
  2. Add the current node to the end of Q.
  3. While Q is not empty:
  4.   Set n equal to the first element of Q.
  5.   Remove first element from Q.
  6.   If n is Inside:
         Set the n
         Add the node to the north of n to the end of Q.
         Add the node to the south of n to the end of Q.
         Add the node to the west of n to the end of Q.
         Add the node to the east of n to the end of Q.
  7. Continue looping until Q is exhausted.
  8. Return.

package samples;

import java.util.ArrayDeque;
import java.util.Queue;

public class FloodFill {

public int[][] floodFill(int[][] image, int sr, int sc, int newColor) {

int oldColor = image[sr][sc];
if (oldColor == newColor)
return image;

Queue<Pair> queue = new ArrayDeque();
queue.add(new Pair(sr, sc));

while (!queue.isEmpty()) {

Pair p = queue.poll();
if (isInside(image, p.i, p.j, oldColor))
set(image, p.i, p.j, newColor);

// up -> row-1
if (isInside(image, p.i - 1, p.j, oldColor))
queue.add(new Pair(p.i - 1, p.j));

// down -> row+1
if (isInside(image, p.i + 1, p.j, oldColor))
queue.add(new Pair(p.i + 1, p.j));

// left -> col-1
if (isInside(image, p.i, p.j - 1, oldColor))
queue.add(new Pair(p.i, p.j - 1));

// right -> col+1
if (isInside(image, p.i, p.j + 1, oldColor))
queue.add(new Pair(p.i, p.j + 1));


return image;

* Set the new color at row i and column j
private void set(int[][] image, int i, int j, int newColor) {
image[i][j] = newColor;

* @return Returns true if (i,j) inside the matrix and of the same old color.
private boolean isInside(int[][] image, int i, int j, int oldColor) {
if (i > -1 && i < image.length && j > -1 && j < image[0].length && image[i][j] == oldColor)
return true;
return false;

class Pair {
int i;
int j;

public Pair(int i, int j) {
this.i = i;
this.j = j;

Thursday, August 29, 2019

Getting Split-Tunneling in Linux to work

In general when you are connected to virtual private network of your office without split tunneling, all the data will go through your vpn network interface.
  1. It makes your system network to work slow as all the data will go through the vpn network.
  2. There might be some domains, websites which might be restricted on vpn network. For eg torrent application is running which might be prohibited in your office network.
The purpose of this article is to allow normal internet traffic via systems default network interface (eth0) and private network traffic via vpn interface (vpn0).

Next >>

The first thing to make sure is that once vpn is connected that it should not be your default route gateway.
This is achieved using vpn profile in Network Manager. Go through the vpn profile in Network Manager settings and check the box as shown below.

Next >>

The route table should look like this. Note the default traffic is still going through eth0 as per the table.

$ route -n
Kernel IP routing table
Destination  Gateway     Genmask Flags Metric Ref Use Iface UG 600 0 0 eth0 U 50 0 0 vpn0 U 1000 0 0 eth0 U 600 0 0 eth0 UH 600 0 0 eth0 UGH 600 0 0 eth0 is the default route, any route which is not matching will end up in this route and go through it.
There may be some extra routes added by the vpn client, so you can keep them. Some VPN servers push the routes from the VPN server so as to make sure the particular range of IP traffic always go through the particular route.
  1. is the endpoint IP through which the vpn traffic flows in and out. This is an internally assigned IP by vpn server. Each and every vpn client will get a different IP.
  2. is the public IP through which the vpn traffic flows via internet. This IP will be common throughout all vpn clients and usually this is the vpn public server IP.

Next >>

Integrate custom script into the system default behavior whenever a vpn client connection is established and terminated.
Let’s assume you have created a vpnscript.

# Don't run until we bring up a real network device
[ "$IFACE" != "lo" ] || exit 0
if [ "$IFACE" = "vpn0" ]; then
if [ "$MODE" = "start" ] && [ "$ADDRFAM" = "inet" ]; then
if [ "$MODE" = "stop" ] && [ "$ADDRFAM" = "inet" ]; then
#do something else
Make the vpnscript functional. You can also copy these scripts to a permanent place. Change $HOME to an absolute path..

sudo ln -vsf $HOME/bin/vpnscript /etc/network/if-up.d/
sudo ln -vsf $HOME/bin/vpnscript /etc/network/if-down.d/
sudo ln -vsf $HOME/bin/vpnscript /etc/network/if-post-down.d/

route add dev vpn0
route add dev vpn0
route add VPN.SYSTEM.IP.0 dev vpn0
route add dns.vpn.ip dev vpn0

dns.vpn.ip could be your vpn dns server, this would also be populated into /etc/resolv.conf once vpn is connected. You can also use two dns servers in this order to make sure if the dns lookup fails in the public server then the VPN dns server is tried for lookup.
  Public/Default DNS server
  VPN DNS server

Manually enter the hosts entries which are contacted frequently. This may not be required if you are only using DNS server approach.


Woof!! That is a lot of networking system but not too much for a networking expert.
Now take a pause and lets understand before moving forward.

Scenario 1:
You want to surf
The public dns server will resolve your dns query to a public IP and the internet traffic goes via eth0

Scenario 2:
You want to do ssh to
The dns query to will fail first via public IP then the system will try to resolve dns query using vpn dns server which will eventually resolve to an IP.
Hint: Try this command first to make sure the dns query is working properly for a vpn domain.

$ dig
; <<>> DiG 9.11.3-1ubuntu1.8-Ubuntu <<>>
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 11024
;; flags: qr rd ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available
; IN A
;; Query time: 0 msec
;; WHEN: Thu Aug 29 20:48:41 IST 2019
;; MSG SIZE rcvd: 78

After the IP is resolved to, the system will check if there a specific route in the routing table. If it is there then it will go through that interface, otherwise the ssh will try to connect it through default route which is eth0.
If it fails then you have to add the route manually like this.

$ sudo route add dev vpn0
#also add it in for future use.

Next >>

Seamless browsing in Firefox/Chrome without worrying about the data traffic. This will also work if your VPN provider has http proxy. In my case I will use socks5 proxy.
  • Install the FoxyProxy Extension/Add-on
  • Select the default mode User proxies based on their pre-defined patterns and priorities.
  • Add a proxy for your vpn provider and enter details.
  • Add the pattern rules for this proxy, for eg: **
  • If there is an option to use proxy for dns then select this option to make sure private domains are resolved via this proxy.
  • Great enjoy!!
Socks5 proxy using ssh
$ ssh -D 5353 -o ConnectTimeout=10 -o ConnectionAttempts=1 -C -N
# -D dynamic socks5 port
# -C compression
# -o for extra option
# -N do not execute any remote command

Monday, September 17, 2018

Simplified Breadth-first Search

Simplified Breadth-first Search

Given a graph G = (V, E) and a distinguished source vertex s, breadth-first search systematically explores the edges of G to “discover” every vertex that is reachable from s. It computes the distance (smallest number of edges) from s to each reachable vertex. It also produces a “breadth-first tree” with root s that contains all reachable vertices. For any vertex reachable from s, the simple path in the breadth-first tree from s to corresponds to a “shortest path” from s to v in G, that is, a path containing the smallest number of edges. The algorithm works on both directed and undirected graphs.


class Graph:
  def __init__(self, nodes):
      self.nodes = nodes
      self.edges = 0
      self.adj = [[] for i in range(self.nodes)]

  def addEdge(self, v, w):
      self.edges += 1

  def bfs(self, startingNode):
      from queue import Queue
      seen = [False for i in range(self.nodes)]
      q = Queue()
      while not q.empty():
          node = q.get()
          print(node, end=", ")
          seen[node] = True
          for neighbour in self.adj[node]:
              if not seen[neighbour]:

Tuesday, September 4, 2018

Disable All Diagnostic Information on your mobile (Android)

In my last post, you have seen how to disable Location History completely. 
In this post I will show you how to disable all the diagnostic logging across Google apps which in turn save you a lot of battery and make our planet less warmer.

There are lot of apps in your Android which might be recording lot of diagnostic information, though the apps are unlimited on play store doing this, however I will keep this list minimal.

Disable all Diagnostic Logging

Most surprising thing here is that most of the settings are enabled by default in most of the apps. You may or may not disable these settings, but there are reasons why you want to do that.
  1. Saves Battery, these tiny settings on different different apps can save you lot of battery and keep your mobile battery healthier.
  2. Privacy, it is a biggest concern you might have:
    1. Do you know what data is being uploaded ?
    2. Your data is stored by so many apps to hundreds of servers across the globe by each app.
    3. Despite lot of privacy rules like GDPR, still there are apps who refused to delete your account. 
  3. End User not as a subject, a mobile user should be an end user rather than interest for studies.


  1. On your Android phone or tablet, open Chrome > Settings Privacy.
  2. Disable Security Reports "Automatically send some system information and page content to Google to help detect dangerous apps and sites".
  3. Tap Usage and crash reports "Automatically send usage statistics and crash reports to Google".
  4. Turn off.


  1. On your Android phone or tablet, open Hangouts > Settings.
  2. Tap your Account, do this for all the accounts shown.
  3. Under Improve Hangouts "Report additional diagnostics to help improve Hangouts".
  4. Turn off.


  1. On your Android phone or tablet, open Maps > Settings.
  2. Tap Commute settings.
  3. Disable Get commute notifications "Know about delays and disruptions before you go".
  4. Disable Get more accurate commute info "Let Maps improve your commute times accuracy by using your Location History".

Sky Map

  1. On your Android phone or tablet, open Sky Map > Settings.
  2. Disable Send usage statistics "Make Sky Map better by sending anonymous data to Google Analytics".


  1. On your Android phone or tablet, open Translate > Settings.
  2. Tap Data usage.
  3. Disable Improve camera input "Let Google retain images for use in product improvement".


  1. On your Android phone or tablet, open Settings > Languages & input.
  2. Tap Virtual keyboard > Gboard. This will open Gboard settings.
  3. Tap Advanced.
  4. Under Improve Gboard.
  5. Disable Share usage statistics "Automatically send keyboard usage statistics to Google".
  6. Disable Share snippets  "Automatically share snippets of what and how you type in Google apps to improve Gboard".
  7. You may have locate the Gboard settings in your mobile.

Google Indic Keyboard settings

  1. On your Android phone or tablet, open Settings > Languages & input.
  2. Tap Virtual keyboard > Google Indic Keyboard. This will open keyboard settings.
  3. Tap Others.
  4. Disable Send usage statistics.

Saturday, August 18, 2018

Disable Google Location Tracking (Android+Web)

You are being tracked by the Amazon, Facebook and Google and most probably you don't even know it. The reason most of the people are not well versed with the intricacies of the mobile ecosystem. The option is enabled by default as soon you buy a new device or you are forced to.
Every place on earth you visit is stored on their servers.

If you think you are targeted for the sake of artificial intelligence or improving user experience and you do not want to be location tracked, then I will guide you through.

Delete your Location History

You can control what’s saved in your Location History, and you can delete your history at any time.

Turn Location History off

You can turn off Location History at the account level at any time and this is the time to do it. When you turn off Location History for your Google Account, it's off for all devices associated with that Google Account.


  1. On your Android phone or tablet, open your device's Settings > Google Google Account.
  2. At the top, tap Data & personalization.
  3. Under "Activity controls," tap Location History.
  4. Turn Location History off for your account.
You have actually paused Location History, however your previous Location History still exists and it can be erased as well. See the next section.


  1. Go to the Activity controls section of your Google Account. Sign in if required.
  2. Turn Location History off.
  3. Confirm the change. This setting will change for your Google Account and all devices associated with it.

Delete Location History

You can delete all of your Location History. If you delete your entire history, only you would be knowing where you had been.
IMPORTANT: Deleting your Location History in the Settings app is permanent. You can't reverse or undo it.


  1. On your Android phone or tablet, open your device's Settings > Google Google Account.
  2. At the top, tap Data & personalization.
  3. Under "Activity controls," tap Location History.
  4. At the bottom, tap Manage Timeline. Your device will open Google Maps.
  5. Tap More > Settings Personal Content.
  6. Under "Location Settings", choose Delete all Location History.


  1. Go to Sign in if required.
  2. Click SettingsDelete all Location history.

Saturday, July 21, 2018

How to use “ok Google” hotword to work when the Screen is Off (root)

In this article, I will be showing you how to use google "ok google" hotword detection when screen is off. This amazing feature is only available for selected high end phones for eg Moto X.

This feature has the ability to listen to "ok google" when display is off so that it can listen to voice command. This feature comes very handy when you have to search anything in google but you are traveling in a car or you are doing something in which you can’t access your smartphone.

In General, you only can hotword detection feature if your device screen is On or your device is connected to the charger so the main thing is that you can’t use this feature when your mobile screen is Off. So basically, this guide will help you to use this feature even when your screen is Off or you aren’t connected to the charger.

How to force “ok google” hotword to work when the Screen is Off (root)


  • Rooted phone 
                A rooted phone gives you full control of your own mobile and it comes with full responsibility.
                Enable Voice detection in Google Search app settings.
                Browse intents and import "Google Now Voice Search" intent.

All Set!!

Sunday, July 2, 2017

Remove all adjacent or consecutive duplicate characters

Remove all adjacent or consecutive duplicate characters

Input:  azxxzy
Output: ay
First "azxxzy" is reduced to "azzy". The string "azzy" contains duplicates, 
so it is further reduced to "ay".

Input: geeksforgeeg
Output: gksfor
First "geeksforgeeg" is reduced to "gksforgg". The string "gksforgg" contains 
duplicates, so it is further reduced to "gksfor".

Input: caaabbbaacdddd
Output: Empty String

Input: acaaabbbacdddd
Output: acac

Iterate through the characters and keep track of duplicates with start and end index, once you get a non matching character then delete the start to end characters and step back one more step and start again.

private static String removeAllAdjacentDuplicates(String s) {
StringBuilder sb = new StringBuilder(s);
int startIndex = -1;
int endIndex = -1;
char previousChar = '\0';
for (int i = 0; i < sb.length(); i++) {
if (previousChar == sb.charAt(i))
endIndex = i;
else {
if (endIndex > startIndex) {
sb.delete(startIndex, endIndex + 1);
i = --startIndex;
i = i < 0 ? 0 : i;
endIndex = -1;
startIndex = i;
previousChar = sb.charAt(i);
if (endIndex > startIndex)
sb.delete(startIndex, endIndex + 1);

return sb.toString();

Note: Deleting is a costly operation for that all the elements will be left shifted with their position.