Related
The question is:
"Given an array A only contains integers Return the number of subarrays that contain at least k different numbers. Subarrays cannot be duplicated."
Example:
input array = {1, 2, 3, 4, 2} k = 3
output: 4
Explanation:
the number of the Subarray with at least K different numbers should be 4,
which are [1, 2, 3] [2, 3, 4] [3, 4, 2] [1, 2, 3, 4]
Right now what I can do is just find about the number of the subarray with exactly K different numbers:
class Solution {
public int subarraysWithKDistinct(int[] A, int K) {
return atMostK(A, K) - atMostK(A, K - 1);
}
private int atMostK(int[] A, int K) {
int i = 0, res = 0;
Map<Integer, Integer> count = new HashMap<>();
for (int j = 0; j < A.length; ++j) {
if (count.getOrDefault(A[j], 0) == 0) K--;
count.put(A[j], count.getOrDefault(A[j], 0) + 1);
while (K < 0) {
count.put(A[i], count.get(A[i]) - 1);
if (count.get(A[i]) == 0) K++;
i++;
}
res += j - i + 1;
}
return res;
}
}
But when the input be:
array = {1, 2, 3, 4, 2} k = 2
my code will not work correctly, but I don't know where to change. Any thoughts? Thanks!
Update: thanks to #MBo and others' answers, I used 2 pointers to fix this problem, but still cannot get the right answer with:
array = {1, 2, 3, 4, 2} k = 3 -> output: 6 (should be 4)
It looks like there are some duplicated substrings be counted, but I don't know how to fix it.
class Solution {
public static void main(String[] args) {
int[] A = {1, 2, 3, 4, 2};
int k = 3;
int res = helper(A, k);
System.out.println(res);
// output is 6, but should be 4
}
private static int helper(int[] A, int k) {
if (A == null || A.length == 0) return 0;
int n = A.length;
int res = 0;
int differentNumbers = 0;
Map<Integer, Integer> counter = new HashMap<>();
int j = 0; // j - 1 is the right point
for (int i = 0; i < n; i ++) {
while (j < n && differentNumbers < k) {
int numOfThisNumber = counter.getOrDefault(A[j], 0);
counter.put(A[j], numOfThisNumber + 1);
if (counter.get(A[j]) == 1) {
differentNumbers ++;
}
j ++;
}
if (differentNumbers == k) {
res += n - j + 1;
}
counter.put(A[i], counter.get(A[i]) - 1);
if (counter.get(A[i]) == 0) {
differentNumbers --;
}
}
return res;
}
}
You can combine your hashmap approach with method of two pointers (indices).
Set both indices into 0 and move right one, updating hashmap counts for values at the right end of interval until hashmap size reaches K. Fix right index.
Now move left index, decreasing counts corresponding to the values at left end. Before every step (including left=0) add size-right to result, because all subarrays starting from left and ending after right, do contain needed number of elements.
When some count becomes 0, remove value from hashmap, and fix left index.
Repeat with right index and so on.
I'm very new to Golang, I'm trying to do a sudoku with backtracking algorithm.
But when I run my program, there are no errors but it only displays the grid not complete, with empty cases here is my code :
package main
import "fmt"
var sudoku = [9][9]int{
{9, 0, 0, 1, 0, 0, 0, 0, 5},
{0, 0, 5, 0, 9, 0, 2, 0, 1},
{8, 0, 0, 0, 4, 0, 0, 0, 0},
{0, 0, 0, 0, 8, 0, 0, 0, 0},
{0, 0, 0, 7, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 2, 6, 0, 0, 9},
{2, 0, 0, 3, 0, 0, 0, 0, 6},
{0, 0, 0, 2, 0, 0, 9, 0, 0},
{0, 0, 1, 9, 0, 4, 5, 7, 0},
}
func main(){
IsValid(sudoku, 0)
Display(sudoku)
}
func Display(sudoku[9][9] int){
var x, y int
for x = 0; x < 9; x++ {
fmt.Println("")
if(x == 3 || x == 6){
fmt.Println(" ")
}
for y = 0; y < 9; y++ {
if(y == 3 || y == 6){
fmt.Print("|")
}
fmt.Print(sudoku[x][y])
}
}
}
func AbsentOnLine(k int, sudoku [9][9]int, x int) bool {
var y int
for y=0; y < 9; y++ {
if (sudoku[x][y] == k){
return false
}
}
return true
}
func AbsentOnRow(k int, sudoku [9][9]int, y int) bool {
var x int
for x=0; x < 9; x++{
if (sudoku[x][y] == k){
return false;
}
}
return true;
}
func AbsentOnBloc(k int, sudoku [9][9]int, x int, y int) bool {
var firstX, firstY int;
firstX = x-(x%3)
firstY = y-(y%3)
for x = firstX; x < firstX+3; x++ {
for y = firstY; y < firstY+3; y++ {
if (sudoku[x][y] == k){
return false;
}
}
}
return true;
}
func IsValid(sudoku [9][9]int, position int) bool {
if (position == 9*9){
return true;
}
var x, y, k int
x = position/9
y = position%9
if (sudoku[x][y] != 0){
return IsValid(sudoku, position+1);
}
for k=1; k <= 9; k++ {
if (AbsentOnLine(k,sudoku,x) && AbsentOnRow(k,sudoku,y) && AbsentOnBloc(k,sudoku,x,y)){
sudoku[x][y] = k;
if (IsValid(sudoku, position+1)){
return true;
}
}
}
sudoku[x][y] = 0;
return false;
}
I'm getting this in the console :
900|100|005
005|090|201
800|040|000
000|080|000
000|700|000
000|026|009
200|300|006
000|200|900
001|904|570
I don't understand why it's not completing the grid, has anyone any ideas ?
I don't know Golang, but I have written a sudoku solving algorithm using backtracking.
Your code only iterates the board once. You start with position=0, your code than iterates over the board ,if a position has the value zero you try values 1-9 and if that doesn't work you go to the next position. When position=81, your code stops.
You added new values to the board with your Isvalid function, but you are not iterating over the new board again to see if those new values help your AbsentOn... function to return a new value that is different than the previous iteration. You have to iterate your board again and again until you are sure that there are no 0 valued cells.
That is the reason you have to many 0 on the board at the end of your program. Your program iterated only once, at It is can not solve your example sudoku on it's first try. It has to add new values to the board and make the sudoku board easier with every iteration.
Another problem is your code does not give a feedback. For example it gives 1 to an empty cell. That seems okey at first, but It doesn't mean that the final value of that cell has to be 1. It may change because in your next iterations you realize that there is another cell that can only take the value 1, so now you have to change back to your initial cell and find a new value other than 1. Your code also fails to do that. That's why humans put some possible values near a cell when they are not sure.
It looks like your problem is with the algorithm. You have to understand the backtracking algorithm. You can try it in another language that you know well first and then migrate it to golang(I wrote mine in C++). Other than that your golang code is easy to read and I don't see any golang related problems.
Your IsValid function changes the contents of the sudoku. The problem is, it actually, in your code as is, changes only a copy of the sudoku. You need to pass it as a pointer if it should change the actual variable.
Here are the changes that you need in your code, it is only five characters:
func main() {
IsValid(&sudoku, 0)
Display(sudoku)
}
// ...
func IsValid(sudoku *[9][9]int, position int) bool {
// ...
if AbsentOnLine(k, *sudoku, x) && AbsentOnRow(k, *sudoku, y) && AbsentOnBloc(k, *sudoku, x, y) {
Given NxN two-dimensional array. Write a function that rotates it by 1 element clockwise (almost circling move).
[1][2][3][4]
[5][6][7][8]
[9][0][1][2]
[3][4][5][6]
Becomes:
[5][1][2][3]
[9][0][6][4]
[3][1][7][8]
[4][5][6][2]
Update:
This was an online interview question - HackerRank. I couldn't solve it. All I found in StackOverflow so far are 90-degree rotation (if you found this question somewhere please share the link in comments).
I'm not very sure what kind of problem you've encountered, as obvious solution works well:
original array:
final int[][] a = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 0, 1, 2}, {3, 4, 5, 6}};
rotation:
for (int i = 0; i < (a.length >>> 1); i++) {
final int minx = i;
final int miny = i;
final int maxx = a.length - 1 - i;
final int maxy = a.length - 1 - i;
int incx = 1, incy = 0;
int prev = a[miny][minx];
for (int x = (minx + 1), y = miny; ((x != minx) || (y != miny)); x += incx, y += incy) {
final int temp = a[y][x];
a[y][x] = prev;
prev = temp;
if ((x == maxx) && (incx == 1)) {
incx = 0;
incy = 1;
}
if ((y == maxy) && (incy == 1)) {
incx = -1;
incy = 0;
}
if ((x == minx) && (incx == -1)) {
incx = 0;
incy = -1;
}
}
a[miny][minx] = prev;
}
output:
5 1 2 3
9 0 6 4
3 1 7 8
4 5 6 2
Another solution in Java.
The row and column distances are declared rather than computed.
final int[][] a = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 0, 1, 2 },
{ 3, 4, 5, 6 } };
final int[][] dRow = { { 1, 0, 0, 0 }, { 1, 1, 0, -1 },
{ 1, 0, -1, -1 }, { 0, 0, 0, -1 } };
final int[][] dCol = { { 0, -1, -1, -1 }, { 0, 0, -1, 0 },
{ 0, 1, 0, 0 }, { 1, 1, 1, 0 } };
int[][] tmp = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 } };
// rotate a to tmp
for (int row = 0; row < a.length; row++)
for (int col = 0; col < a[row].length; col++)
tmp[row][col] = a[row + dRow[row][col]][col + dCol[row][col]];
// copy tmp to a
for (int row = 0; row < a.length; row++)
for (int col = 0; col < a[row].length; col++)
a[row][col] = tmp[row][col];
// show result
for (int row = 0; row < a.length; row++)
for (int col = 0; col < a[row].length; col++)
System.out.print((col == 0 ? "\n" : "") + a[row][col]);
I quickly gave this a go, with a slightly different approach in Python for square matrix (you specified NxN). For each layer, I unwrap, rotate and re-apply. This is definitely more work than necessary, but was easy to trace and felt logical - and works for +-n step rotation.
def rotate_matrix(m, n):
assert len(m) is len(m[0]), 'Assertion: rotation requires square matrix'
rotated_matrix = [[None] * len(m[0]) for _ in range(len(m))]
def _rotate_layer(ns):
return ns[n:] + ns[:n]
def _nth_layer(l):
left = [m[i][l-1] for i in range(l-1, len(m)-(l-1))]
bottom = m[len(m)-1-(l-1)][l:len(m)-(l-1)]
right = [m[i][len(m[0])-l] for i in reversed(range(l-1, len(m)-l))]
upper = m[l-1][len(m[0])-l-1:l-1:-1]
return left + bottom + right + upper
def _apply_layer(l):
ns = _rotate_layer(_nth_layer(l))
for i in range(l-1, len(m)-(l-1)):
rotated_matrix[i][l-1] = ns.pop(0)
for i in range(l, len(m)-(l-1)):
rotated_matrix[len(m)-1-(l-1)][i] = ns.pop(0)
for i in reversed(range(l-1, len(m)-l)):
rotated_matrix[i][len(m[0])-l] = ns.pop(0)
for i in reversed(range(l, len(m[0])-l)):
rotated_matrix[l-1][i] = ns.pop(0)
for i in range(1, len(m)/2+1):
_apply_layer(i)
return rotated_matrix
I have a algorithm design puzzle that I could not solve.
The puzzle is formulated like this: There are N persons standing on a number line, each of them maybe standing on any integer number on that line. Multiple persons may stand on the same number. For any two persons to be able to communicate with each other, the distance between them should be less than K. The goal is to move them so that each pair of two persons can communicate each other (possibly via other people). In other words, we need to move them so that the distance between any neighboring two persons is smaller than K.
Question: What is the minimum number of total moves? It feels like this falls into greedy algorithm family or dynamic programming. Any hints are appreciated!
We can do the following in O(n):
Calculate the cost of moving all people to the right of person i towards person i at an acceptable distance:
costRight(A[i]) = costRight(A[i+1]) + (A[i+1] - A[i] - k + 1) * count of people to the right
K = 3; A = { 0, 3, 11, 17, 21}
costRight = {32, 28, 10, 2, 0}
Calculate the cost of moving all people to the left of person i towards person i at an acceptable distance:
costLeft(A[i]) = costLeft(A[i-1]) + (A[i] - A[i-1] - k + 1) * count of people to the left
K = 3; A = { 0, 3, 11, 17, 21}
costLeft = { 0, 1, 13, 25, 33}
costRight = {32, 28, 10, 2, 0}
Now that we have cost from both directions we can do this in O(n):
minCost = min(costRight + costLeft) for all A[i]
minCost = min(32 + 0, 28 + 1, 13 + 10, 25 + 2, 33 + 0) = 23
But sometimes that's no enough:
K = 3; A = { 0, 0, 1, 8, 8}
carry: -2 -4 3
costLeft = { 0, 0, 0, 11, 11}
carry: -3 5 -2
costRight = { 8, 8, 8, 0, 0}
The optimum is neither 11 nor 8. Test the current best by moving towards the greatest saving:
move 1 to 2, cost = 1
K = 3; A = { 0, 0, 2, 8, 8}
carry: -2 -2 -10
costLeft = { 0, 0, 0, 10, 10}
carry: -2 -2
costRight = { 6, 6, 6, 0, 0}
minCost = 1 + min(0 + 6, 0 + 6, 0 + 6, 10 + 0, 10 + 0) = 1 + 6 = 7
Not quite sure how to formularize this efficiently.
Here is a greedy algorithm written in Java, but I don't know if it gives the optimal solution in every case. Also it is more a proof of concept, there is some room for optimizations.
It is based on the fact that two neighbouring persons must not be more than K apart, the next neighbour must not be more than 2K away and so on. In each step we move the person that "violates these constraints most". The details of this calculation are in method calcForce.
package so;
import java.util.Arrays;
public class Main {
public static void main(String args[]) {
int[] position = new int[] {0, 0, 5, 11, 17, 23};
int k = 5;
solve(position, k);
}
private static void solve(int[] position, int k) {
if (!sorted(position)) {
throw new IllegalArgumentException("positions must be sorted");
}
int[] force = new int[position.length];
int steps = 0;
while (calcForce(position, k, force)) {
int mp = -1;
int mv = -1;
for (int i = 0; i < force.length; i++) {
if (mv < Math.abs(force[i])) {
mv = Math.abs(force[i]);
mp = i;
}
}
System.out.printf("move %d to the %s%n", mp, force[mp] > 0 ? "right" : "left");
if (force[mp] > 0) {
position[mp]++;
} else {
position[mp]--;
}
steps++;
}
System.out.printf("total: %d steps%n", steps);
}
private static boolean calcForce(int[] position, int k, int[] force) {
boolean commProblem = false;
Arrays.fill(force, 0);
for (int i = 0; i < position.length - 1; i++) {
for (int j = i + 1; j < position.length; j++) {
int f = position[j] - position[i] - (j - i) * k;
if (f > 0) {
force[i] += f;
force[j] -= f;
commProblem = true;
}
}
}
return commProblem;
}
private static boolean sorted(int[] position) {
for (int i = 0; i < position.length - 1; i++) {
if (position[i] > position[i+1]) {
return false;
}
}
return true;
}
}
I have the following function to sort an unordered array to having even numbers in the front and odd numbers in the back. Is there a way to get it done without using any loops?
//front is 0, back =array.length-1;
arrangeArray (front, back);
public static void arrangeArray (int front, int back)
{
if (front != back || front<back)
{
while (numbers [front]%2 == 0)
front++;
while (numbers[back]%2!=0)
back--;
if (front < back)
{
int oddnum = numbers [front];
numbers[front]= numbers[back];
numbers[back]=oddnum;
arrangeArray (front+1, back-1);
}
}
}
Mergesort is fairly trivial to code without loops:
void mergesort(int lo, int hi)
{
if (lo<hi)
{
int m=(lo+hi)/2;
mergesort(lo, m);
mergesort(m+1, hi);
merge(lo, m, hi);
}
}
I'll leave making it sort even/odd as an exercise to the reader :)
(Sounds like homework)
When you do recursion, you have a base step and a recursive step.
In this case, the base condition is when front == back, because you start from the edges and end up in the middle. When you get to the middle you know it's done.
Before you do the recursive step, you have to do a bit of sorting. You're only doing the sorting one step at a time, so only deal with the elements at array[front] and array[back] for now. After you arrange those into the right place, do a recursive call.
You'll end up with something like this:
public static void arrangeArray (int front, int back)
{
if(front >= back) return;
int f = numbers[front];
int b = numbers[back];
if(f%2 == 0) {
front++;
} else {
numbers[back] = f;
back--;
}
if (b%2 == 0) {
numbers[front] = b;
front++;
} else {
back--;
}
arrangeArray(front, back);
}
It's untested and probably doesn't work for edge conditions, but it's a good start :)
Wouldn't that simply be:
//front is 0, back =array.length-1;
arrangeArray (front, back);
public static void arrangeArray (int front, int back)
{
if (front != back || front<back)
{
if (numbers [front]%2 == 0)
arrangeArray (front+1, back);
else
if (numbers[back]%2!=0)
arrangeArray (front, back-1);
else
if (front < back)
{
int oddnum = numbers [front];
numbers[front]= numbers[back];
numbers[back]=oddnum;
arrangeArray (front+1, back-1);
}
}
}
?
May I recommend this Python snippet to inspire high level thinking?
compare = lambda x,y: x - y if x%2 == y%2 else y%2 - x%2
>>> sorted([3,4,2,1,5,6,7,90,23,44], cmp=compare)
[1, 3, 5, 7, 23, 2, 4, 6, 44, 90]
I think one needs to build a comparator function that returns negative, 0, and positive and use that.
What you want to do is
arrangeArray(front, back, bool recursed=false) {
if (recursed) {
arrangeArray(front, back/2, true);
return arrangeArray(back/2, back, true);
}
// Do stuff here.
}
The following should be instructive. It's a recursive O(N) solution that rearranges the even numbers in front and odd numbers in the back, but doesn't do any ordering beyond that.
static boolean isEven(int n) {
return (n & 1) == 0;
}
static boolean isOdd(int n) {
return !isEven(n);
}
static int[] swapped(int[] nums, int i, int j) {
int t = nums[i];
nums[i] = nums[j];
nums[j] = t;
return nums;
}
static int[] arrange(int[] nums, int lo, int hi) {
return
(lo >= hi) ? nums :
(isEven(nums[lo])) ? arrange(nums, lo + 1, hi) :
(isOdd(nums[hi])) ? arrange(nums, lo, hi - 1) :
arrange(swapped(nums, lo, hi), lo + 1, hi - 1);
}
static void evenOddSort(int... nums) {
System.out.println(java.util.Arrays.toString(
arrange(nums, 0, nums.length - 1)
));
}
public static void main(String[] args) {
evenOddSort(1,3,5,7,2,4,6);
} // prints "[6, 4, 2, 7, 5, 3, 1]"
I think the ternary operator makes the recursion flow more naturally, but if you're not that comfortable with how it works, you can just use traditional if-else.
static int[] arrange(int[] nums, int lo, int hi) {
if (lo >= hi) {
return nums;
} else if (isEven(nums[lo])) {
return arrange(nums, lo + 1, hi);
} else if (isOdd(nums[hi])) {
return arrange(nums, lo, hi - 1);
} else {
return arrange(swapped(nums, lo, hi), lo + 1, hi - 1);
}
}