@Contract(pure=true) public static int difference(@NotNull String s1,@NotNull String s2){
  int[][] a=new int[s1.length()][s2.length()];
  for (int i=0; i < s1.length(); i++) {
    a[i][0]=i;
  }
  for (int j=0; j < s2.length(); j++) {
    a[0][j]=j;
  }
  for (int i=1; i < s1.length(); i++) {
    for (int j=1; j < s2.length(); j++) {
      a[i][j]=Math.min(Math.min(a[i - 1][j - 1] + (s1.charAt(i) == s2.charAt(j) ? 0 : 1),a[i - 1][j] + 1),a[i][j - 1] + 1);
    }
  }
  return a[s1.length() - 1][s2.length() - 1];
}

@ Contract ( pure = true ) public static int difference ( @ NotNull String s1 , @ NotNull String s2 ) { int [ ] [ ] a = new int [ s1 . length ( ) ] [ s2 . length ( ) ] ; for ( int i = 0 ; i < s1 . length ( ) ; i ++ ) { a [ i ] [ 0 ] = i ; } for ( int j = 0 ; j < s2 . length ( ) ; j ++ ) { a [ 0 ] [ j ] = j ; } for ( int i = 1 ; i < s1 . length ( ) ; i ++ ) { for ( int j = 1 ; j < s2 . length ( ) ; j ++ ) { a [ i ] [ j ] = Math . min ( Math . min ( a [ i - 1 ] [ j - 1 ] + ( s1 . charAt ( i ) == s2 . charAt ( j ) ? 0 : 1 ) , a [ i - 1 ] [ j ] + 1 ) , a [ i ] [ j - 1 ] + 1 ) ; } } return a [ s1 . length ( ) - 1 ] [ s2 . length ( ) - 1 ] ; }
classic dynamic programming algorithm for string differences .
