1. Java pass by value or pass by reference
Java is ALWAYS pass-by-value (meaning make another new copy ).
That’s why when we change object’s value within function, the original object’s value is untouchable.
Reference:
|
Java is ALWAYS pass-by-value (meaning make another new copy ).
That’s why when we change object’s value within function, the original object’s value is untouchable.
Reference:
|
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.HashMap;
import java.util.TreeMap;
import java.util.Map.Entry;
import java.util.Collections;
class QueueEntry
{
TreeNode node;
int horizontalDistance;
QueueEntry(TreeNode node, int horizontalDistance)
{
this.node = node;
this.horizontalDistance = horizontalDistance;
}
}
class TreeNode
{
TreeNode left;
TreeNode right;
int val;
public TreeNode(int x)
{
this.val = x;
}
}
public class PrintVerticalLevelNodesSum {
/*
Output
1. Expected Output -
4
2
1 5 6
3 8
7
2. HashMap Output -
1,5,6,
8,3,
7,
4,
2,
3. TreeMap (key:level=>in order) Output
4,
2,
1,5,6,
8,3,
7,
4. Collections.sort() Output
4,
2,
1,5,6,
3,8,
7,
Output for sum
4,
2,
12,
11,
7
*/
public static void main(String[] arg)
{
PrintVerticalLevelNodesSum tree = new PrintVerticalLevelNodesSum();
/*
1
2 3
4 5 6 7
8
*/
TreeNode root = tree.createTree();
tree.printVerticalOrder(root);
}
public TreeNode createTree()
{
TreeNode root = new TreeNode(1);
TreeNode n1 = new TreeNode(2);
TreeNode n2 = new TreeNode(3);
TreeNode n3 = new TreeNode(4);
TreeNode n4 = new TreeNode(5);
TreeNode n5 = new TreeNode(6);
TreeNode n6 = new TreeNode(7);
TreeNode n7 = new TreeNode(8);
root.left = n1;
root.right = n2;
n1.left = n3;
n1.right = n4;
n2.left = n5;
n2.right = n6;
n4.right = n7;
return root;
}
// Main Function
public static void printVerticalOrder(TreeNode root){
if(root == null) return;
//HashMap> map = new HashMap>();
TreeMap> map = new TreeMap>();
printVerticalOrderUtilRecursive(root, 0, map);
//printVerticalOrderUtilInterative(root,0,map);
TreeMap mapSum = new TreeMap();
printVerticalOrderSumUtilRecursive(root, 0, mapSum);
// Print
System.out.println("vertical nodes :" );
for(Integer level: map.keySet()){
ArrayList tmp = map.get(level);
Collections.sort(tmp);
for(Integer value: tmp)
System.out.print(value + ",");
System.out.println();
}
System.out.println();
System.out.println("vertical sum :" );
for(Integer level: mapSum.keySet()){
int tmp = mapSum.get(level);
System.out.print(tmp + ",");
System.out.println();
}
}
//private static void printVerticalOrderUtil(TreeNode root, int level,
// HashMap> map) {
private static void printVerticalOrderUtilRecursive(TreeNode root, int level, TreeMap> map) {
// Base Case, root == null
if(root == null) return;
// Base Case, root != null
ArrayList list = (map.get(level) != null)? map.get(level): new ArrayList();
list.add(root.val);
map.put(level, list);
// Recursive
printVerticalOrderUtilRecursive(root.left, level-1, map);
printVerticalOrderUtilRecursive(root.right, level+1, map);
}
private static void printVerticalOrderUtilInterative(TreeNode root, int level, TreeMap> map)
{
if (root == null) return;
ArrayList mapEntry;
LinkedList queue = new LinkedList();
queue.add(new QueueEntry(root, level));
while (!queue.isEmpty())
{
QueueEntry entry = queue.remove();
// Base Case, root != null
mapEntry = (map.get(entry.horizontalDistance) != null)? map.get(entry.horizontalDistance):new ArrayList();
mapEntry.add(entry.node.val);
map.put(entry.horizontalDistance, mapEntry);
if (entry.node.left != null)
{
queue.add(new QueueEntry(entry.node.left, entry.horizontalDistance - 1));
}
if (entry.node.right != null)
{
queue.add(new QueueEntry(entry.node.right, entry.horizontalDistance + 1));
}
}
}
private static void printVerticalOrderSumUtilRecursive(TreeNode root, int level, TreeMap map) {
// Base Case, root == null
if(root == null) return;
// Base Case, root != null
int sum = (map.get(level) != null)? map.get(level)+root.val: root.val;
map.put(level, sum);
// Recursive
printVerticalOrderSumUtilRecursive(root.left, level-1, map);
printVerticalOrderSumUtilRecursive(root.right, level+1, map);
}
private static void printVerticalOrderSumUtilInterative(TreeNode root, int level,TreeMap map)
{
if (root == null) return;
ArrayList mapEntry;
LinkedList queue = new LinkedList();
queue.add(new QueueEntry(root, level));
while (!queue.isEmpty())
{
QueueEntry entry = queue.remove();
// Base Case, root != null
int sum = (map.get(entry.horizontalDistance) != null)? map.get(entry.horizontalDistance)+ root.val: root.val;
map.put(entry.horizontalDistance, sum);
if (entry.node.left != null)
{
queue.add(new QueueEntry(entry.node.left, entry.horizontalDistance - 1));
}
if (entry.node.right != null)
{
queue.add(new QueueEntry(entry.node.right, entry.horizontalDistance + 1));
}
}
}
}
//list can not set -1, sum
//sh-4.3$ java -Xmx128M -Xms16M PrintVerticalLevelNodesSum
//Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
// at java.util.ArrayList.rangeCheck(ArrayList.java:635)
// at java.util.ArrayList.get(ArrayList.java:411)
// at PrintVerticalLevelNodesSum.printVerticalOrderSumUtilRecursive(PrintVerticalLevelNodesSum.java:185)
// at PrintVerticalLevelNodesSum.printVerticalOrder(PrintVerticalLevelNodesSum.java:120)
// at PrintVerticalLevelNodesSum.main(PrintVerticalLevelNodesSum.java:84)
import java.lang.*;
public class BIT2DSumAndUpdate {
// Given an NxN matrix of positive and negative integers, write code to find the
// range sum and update matrix
// Approach#1 sum: O(n^2) time, update:O(1) time.
static int sum(int[][] matrix, int r1, int c1, int r2, int c2) {
int sum = 0;
for (int r = r1; r <= r2; ++r) {
for (int c = c1; c <= c2; ++c) {
sum += matrix[r][c];
}
}
return sum;
}
static void update (int[][] matrix, int r1, int c1, int val){
matrix[r1][c1] = val;
}
// Approach#2 sum: O(1) time, update:O(n^2) time.
static int[][] processMatrix(int[][] m) {
if (m == null) return null;
int[][] sumMatrix = new int[m.length][m[0].length];
sumMatrix[0][0] = m[0][0];
for (int j = 1; j < m[0].length;j++){
sumMatrix[0][j]=sumMatrix[0][j-1]+m[0][j];
//System.out.println(0+","+j+" - "+sumMatrix[0][j]+",");
}
for (int i = 1; i < m.length;i++){
sumMatrix[i][0]=sumMatrix[i-1][0]+m[i][0];
//System.out.println(i+","+0+" - "+sumMatrix[i][0]+",");
}
for (int i =1; i< m.length;i++) {
for (int j=1; j < m[0].length;j++){
sumMatrix[i][j] = sumMatrix[i-1][j]+sumMatrix[i][j-1]-sumMatrix[i-1][j-1]+m[i][j];
//System.out.println(i+","+j+" - "+sumMatrix[i][j]+",");
}
}
return sumMatrix;
}
static int sum2(int[][] sumMatrix, int r1, int c1, int r2, int c2) {
if (r1 == 0 && c1 == 0){
return sumMatrix[r2][c2];
}
else if (r1 == 0){
return sumMatrix[r2][c2]-sumMatrix[r2][c2-1];
}
else if (c1 == 0 ){
return sumMatrix[r2][c2]-sumMatrix[r1-1][c2];
} else {
return sumMatrix[r2][c2]-sumMatrix[r2][c1-1]-sumMatrix[r1-1][c2]+sumMatrix[r1-1][c1-1];
}
}
static void update2(int[][] matrix, int[][] sumMatrix,int r1, int c1, int val){
int diff= val - matrix[r1][c1];
for (int i = r1; i < sumMatrix.length;i++){
for (int j = c1; j< sumMatrix[0].length; j++){
sumMatrix[i][j]+=diff;
}
}
}
// Approach#3 sum: O(log n) time, update:O(log n) time.
static int[][] processMatrixTree(int[][] m) {
if (m == null) return null;
int[][] tree = new int[m.length+1][m[0].length+1];
for( int i = 1; i <= m.length;i++){
for(int j = 1; j <=m[0].length;j++){
//System.out.println(i+","+j+". sumFirst="+tree[i][j]);
updateBuilde3(tree, i, j, m[i-1][j-1]);
}
}
return tree;
}
static int sum3(int[][] tree, int r1, int c1, int r2, int c2) {
if (r1 == 0 && c1 == 0){
return getSum(tree,r2,c2);
}
else if (r1 == 0){
return getSum(tree,r2,c2)-getSum(tree,r2,c2-1);
}
else if (c1 == 0 ){
return getSum(tree,r2,c2)-getSum(tree,r1-1, c2);
} else {
return getSum(tree,r2,c2)-getSum(tree,r2,c1-1)-getSum(tree,r1-1, c2)+getSum(tree,r1-1,c1-1);
}
}
static int getSum(int[][] tree, int i, int j){
int sum = 0;
//System.out.println(i+","+j+". sumAdd="+sum);
i = i+1;
j = j+1;
int j1;
while(i > 0) {
j1 = j;
while(j1 > 0){
sum += tree[i][j1];
///System.out.println(i+","+j1+". sumAdd="+sum);
j1 -= j1 & -j1;
}
i -= i & -i;
}
return sum;
}
static void updateBuilde3(int[][] tree, int i, int j, int val){
//int diff= val - matrix[r1][c1];
int j1;
while(i < tree.length){
j1 = j;
while(j1 < tree[0].length){
tree[i][j1] += val;
//System.out.println(i+","+j1+". sumAfter="+tree[i][j1]);
j1 += (j1 & -j1);
}
i += (i & -i);
}
}
static void update3(int[][] matrix, int[][] tree, int i, int j, int val){
int diff= val - matrix[i][j];
int j1;
while(i < tree.length){
j1 = j;
while(j1 < tree[0].length){
tree[i][j1] += diff;
//System.out.println(i+","+j1+". sumAfter="+tree[i][j1]);
j1 += (j1 & -j1);
}
i += (i & -i);
}
}
//--------------------------------------
public static void main(String[]args) {
int[][] m = {
{1,-2,3,1},
{1,5,-4,1},
{1,1,0,2},
{-1,1,1,-8}};
int[][] m2 = {
{1,-2,3,1},
{1,5,-4,1},
{1,1,0,2},
{-1,1,1,-8}};
int[][] m3 = {
{1,-2,3,1},
{1,5,-4,1},
{1,1,0,2},
{-1,1,1,-8}};
long start = System.nanoTime();
int sum1_1 = sum(m,0,0,2,3);
long end = System.nanoTime();
update(m, 2,3,3);// 2->3
int sum1_2 = sum(m,0,0,2,3);
System.out.println("Time:"+(long)(end-start)+",sum=" +sum1_1+",sum2=" +sum1_2);
int[][] sumMatrix = processMatrix(m2);
long start2 = System.nanoTime();
int sum2_1 = sum2(sumMatrix,0,0,2,3);
long end2 = System.nanoTime();
update2(m2, sumMatrix, 2,3,3);// 2->3
int sum2_2 = sum2(sumMatrix,0,0,2,3);
System.out.println("Time:"+(long)(end2-start2)+",sum=" +sum2_1+",sum2=" +sum2_2);
int[][] tree = processMatrixTree(m3);
long start3 = System.nanoTime();
int sum3_1 = sum3(tree,0,0,2,3);
long end3 = System.nanoTime();
update3(m3, tree, 2,3,3);// 2->3
int sum3_2 = sum3(tree,0,0,2,3);
System.out.println("Time:"+(long)(end3-start3)+",sum=" +sum3_1+",sum2=" +sum3_2);
}
}