Leetcode 2360 Longest Cycle in a Graph - graph

I use nearly the same method as in the discussion. But mine reaches the time limitation but his passes all cases. I want to know how to improve my code and why there is difference?
Here is my entire code:
boolean[] visited;
public int dfs(int step, int[] edges, int node, Map<Integer, Integer> path) {
path.put(node, step);
visited[node] = true;
if (edges[node] == -1) {
return -1;
}
if (path.containsKey(edges[node])) {
return step - path.get(edges[node]) + 1;
}
return dfs(step + 1, edges, edges[node], path);
}
public int longestCycle(int[] edges) {
int res = -1;
visited = new boolean[edges.length];
for (int i = 0; i < edges.length; i++) {
if (visited[i]) {
continue;
}
int maxCircleLength = dfs(0, edges, i, new HashMap<Integer, Integer>());
res = Math.max(maxCircleLength, res);
}
return res;
}
This is his solution:
public int longestCycle(int[] edges) {
int longest = -1;
boolean visited[] = new boolean[edges.length]; // global visisted
HashMap<Integer, Integer> map;
for(int i=0; i<edges.length; i++){
if(visited[i]) continue;
int distance = 0, curr_node = i;
map = new HashMap<>(); // local visited
while(curr_node != -1){
if(map.containsKey(curr_node)){
longest = Math.max(longest, distance - map.get(curr_node));
break;
}
if(visited[curr_node]) break;
visited[curr_node] = true;
map.put(curr_node, distance);
curr_node = edges[curr_node];
distance++;
}
}
return longest;
}

Related

FloodFill method not working properly. (Recursion)

I am trying to make minesweeper game. Everything is working fine except the floodFill method. Once the floodFill method reveals one number, the recursion stops. I do not want the recursion to stop but go on so that it checks other neighbors as well but it does not. I am not sure what I am doing wrong.
package zProject_MineSweeper;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.*;
import javax.swing.JPanel;
public class MyPanel extends JPanel{
/**
*
*/
private static final long serialVersionUID = 1L;
static final int screenW = 600;
static final int screenH = 600;
static final int unitSize = 40;
static final int rowsNum = screenW/unitSize;
static final int colsNum = screenH/unitSize;
// In this code i have defined bomb as -5
static final int bombNum = -5;
static final int bombGap = 10;
static final double bombProb = 0.05;
static final int fontSize = 20;
int[][] values;
boolean[][] path;
Random random;
MyPanel(){
initializeAll();
initializeValues();
}
private void initializeAll() {
this.addMouseListener(new MyMouseListeners());
this.setPreferredSize(new Dimension(screenW,screenH));
this.setFocusable(true);
this.setBackground(new Color(200,200,200));
random = new Random();
values = new int[rowsNum][colsNum];
path = new boolean[rowsNum][colsNum];
}
private void initializeValues() {
double randomBombProb;
for(int i=0; i<rowsNum; i++) {
for(int j=0; j<colsNum; j++) {
path[i][j] = false;
}
}
for(int i=0; i<rowsNum; i++) {
for(int j=0; j<colsNum; j++) {
randomBombProb = random.nextDouble();
if (randomBombProb< bombProb) {
values[i][j] = bombNum;
}
}
}
for(int i=0; i<rowsNum; i++) {
for(int j=0; j<colsNum; j++) {
if (values[i][j] != bombNum) {
setNumbers(i,j);
}
}
}
}
private void setNumbers(int i, int j) {
//Check number of bombs near each node
int sum = 0;
for(int x=-1; x<2; x++) {
for(int y=-1; y<2; y++) {
int rowx = (i + x + rowsNum) / rowsNum;
int coly = (j + y + colsNum) / colsNum;
if (rowx==1 && coly==1) {
if(values[i+x][j+y] == bombNum) {
sum++;
}
}
}
}
values[i][j] = sum;
}
public void floodFill(int i, int j) {
if(values[i][j]==0) {
for(int x=-1; x<2; x++) {
for(int y=-1; y<2; y++) {
int rowx = (i + x + rowsNum)/rowsNum;
int coly = (j + y + colsNum)/colsNum;
if (rowx == 1 && coly == 1 && !path[i][j]) {
path[i][j] = true;
floodFill(i+x,j+y);
}
}
}
}
else {
path[i][j] = true;
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
draw(g);
}
private void draw(Graphics g) {
g.setFont(new Font("Times Roman", Font.BOLD, fontSize));
FontMetrics metrics = getFontMetrics(g.getFont());
for(int i=0; i<rowsNum; i++) {
for(int j=0; j<colsNum; j++) {
if (path[i][j]==true) {
drawValue(g,metrics,i,j);
}
else {
g.setColor(new Color(120,120,120));
g.fillRect(i*unitSize, j*unitSize, unitSize, unitSize);
}
}
}
drawGrid(g);
}
private void drawValue(Graphics g, FontMetrics metrics,int i, int j) {
// Centering the numbers in each cell
if (values[i][j] != bombNum) {
g.setColor(new Color(10,10,10));
g.drawString("" + values[i][j],
i*unitSize + unitSize/2 - metrics.stringWidth("" + values[i][j])/2,
j*unitSize + unitSize/2 + fontSize/2);
}
else {
g.setColor(Color.RED);
g.fillOval(i*unitSize+bombGap, j*unitSize+bombGap, unitSize-(2*bombGap), unitSize-(2*bombGap));
}
}
private void drawGrid(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(2));
g2.setColor(new Color(10,10,10));
for(int i=0; i<rowsNum; i++) {
g2.drawLine(unitSize*i, 0, unitSize*i, screenH);
}
for(int i=0; i<colsNum; i++) {
g2.drawLine(0, unitSize*i, screenW, unitSize*i);
}
}
public class MyMouseListeners implements MouseListener {
public void mouseClicked(MouseEvent e) {
if(e.getButton() == 1) {
int i = e.getX()/unitSize;
int j = e.getY()/unitSize;
floodFill(i, j);
repaint();
}
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
}
}

Maximum Xor between Two Arrays | Trie

Given two integer vectors A and B, we have to pick one element from each vector such that their xor is maximum and we need to return this maximum xor value from the function int Solution::solve(vector &A, vector &B).
I found out that the code below is not passing all the test cases when I'm declaring and initializing the head pointer globally right beneath the class Trienode. Why is that?
Code
class Trienode
{
public:
Trienode* left;
Trienode* right;
Trienode()
{
left=0;
right=0;
}
};
// Trienode* head = new Trienode;
int Max_Xor_Pair(Trienode* head, vector<int> B)
{
int n=B.size();
int max_xor=INT_MIN;
for(int i=0; i<n; i++)
{
int pair1 = B[i];
int pair2 = 0;
Trienode* curr=head;
for(int j=31; j>=0; j--)
{
int bit = (pair1>>j)&1;
if(bit)
{
if(curr->left)
curr=curr->left;
else
{
curr=curr->right;
pair2 += pow(2,j);
}
}
else
{
if(curr->right)
{
curr=curr->right;
pair2 += pow(2,j);
}
else
curr=curr->left;
}
}
int curr_xor = pair1 ^ pair2;
max_xor = max(max_xor, curr_xor);
}
return max_xor;
}
void Insert(Trienode* head, int num)
{
Trienode* curr=head;
for(int i=31; i>=0; i--)
{
int x = num;
int bit= (x>>i)&1;
if(bit)
{
if(!curr->right)
{
Trienode* temp = new Trienode;
curr->right=temp;
}
curr=curr->right;
}
else
{
if(!curr->left)
{
Trienode* temp = new Trienode;
curr->left=temp;
}
curr=curr->left;
}
}
}
int Solution::solve(vector<int> &A, vector<int> &B) {
Trienode* head = new Trienode;
for(int x:A)
Insert(head,x);
return Max_Xor_Pair(head,B);
}
Sample Input
A : [ 15891, 6730, 24371, 15351, 15007, 31102, 24394, 3549, 19630, 12624, 24085, 19955, 18757, 11841, 4967, 7377, 13932, 26309, 16945, 32440, 24627, 11324, 5538, 21539, 16119, 2083, 22930, 16542, 4834, 31116, 4640, 29659, 22705, 9931, 13978, 2307, 31674, 22387, 5022, 28746, 26925, 19073, 6271, 5830, 26778, 15574, 5098, 16513, 23987, 13291, 9162 ]
B : [ 18637, 22356, 24768, 23656, 15575, 4032, 12053, 27351, 1151, 16942 ]
When head is a global variable, and you don't have this line in Solution::solve:
Trienode* head = new Trienode;
...then head will retain its value after the first test case has finished, and so the second test case will not start with an empty tree. Each test case will add more nodes to the one tree. Of course this means that, except for the first test case, the tree rooted by head is not the intended tree.
To make the version with the global variable work, reset it in Solution::solve:
head->left = head->right = nullptr;
BTW, you should also initialise these members with nullptr (instead of 0) in your TrieNode constructor. This better reflects the intent.
You can also go with this approach:
Code:
struct Node {
Node* left;
Node* right;
};
class MaxXorHelper{
private : Node* root;
public :
MaxXorHelper() {
root = new Node();
}
void addElements(vector<int> &arr) {
for(int i=0; i<arr.size(); i++) {
Node* node = root;
int val = arr[i];
for(int j=31; j>=0; j--) {
int bit = (val >> j) & 1;
if(bit == 0) {
if(!node->left) {
node->left = new Node();
}
node = node->left;
}
else {
if(!node->right) {
node->right = new Node();
}
node = node->right;
}
}
}
}
int findMaxXor(vector<int> &arr) {
int maxXor = INT_MIN;
for(int i=0; i<arr.size(); i++) {
Node* node = root;
int val2 = 0;
int val1 = arr[i];
for(int j=31; j>=0; j--) {
int bit = (val1 >> j) & 1;
if(bit == 0) {
if(node->right) {
val2 |= (1 << j);
node = node->right;
} else{
node = node->left;
}
}
else {
if(node->left) {
node = node->left;
} else{
val2 |= (1 << j);
node = node->right;
}
}
}
int curXor = val1 ^ val2;
maxXor = max(maxXor, curXor);
}
return maxXor;
}
};
int Solution::solve(vector<int> &A, vector<int> &B) {
MaxXorHelper helper;
helper.addElements(A);
return helper.findMaxXor(B);
}

Beginner coder checking if input is part of a cycle?

public Graph (int nb){
this.nbNodes = nb;
this.adjacency = new boolean [nb][nb];
for (int i = 0; i < nb; i++){
for (int j = 0; j < nb; j++){
this.adjacency[i][j] = false;
}
}
}
public void addEdge (int i, int j){
if(!(i<0 || i>=this.nbNodes|| j<0 || j>=this.nbNodes))
{
this.adjacency[i][j] = true;
this.adjacency[j][i] = true;
}
}
public void removeEdge (int i, int j){
if(!(i<0 || i>=this.nbNodes|| j<0 || j>=this.nbNodes))
{
this.adjacency[i][j] = false;
this.adjacency[j][i] = false;
}
}
public int nbEdges(){
int c =0;
for(int i=0; i<this.nbNodes; i++)
{
for(int j= 0; j<this.nbNodes; j++)
{
if(this.adjacency[i][j]==true)
{
c++;
}
}
}
return c/2;
}
public boolean cycle(int start){
return false;
}
A Graph has a number of nodes nbNodes and is characterized by its adjacency matrix adjacency. adjacency[i][j] states whether or not there is an edge from the i-th node to the j-th node.
the graphs are undirected.
I am a beginner coder and am having trouble writing cycle(int start)
It takes as input an integer, g.cycle(i) returns true if the i-th node is part of a cycle (and false otherwise).
does anyone have any idea on how I should approach this?

Alternative to System.Web.Security.Membership.GeneratePassword in aspnetcore (netcoreapp1.0)

Is there any alternative to System.Web.Security.Membership.GeneratePassword in AspNetCore (netcoreapp1.0).
The easiest way would be to just use a Guid.NewGuid().ToString("n") which is long enough to be worthy of a password but it's not fully random.
Here's a class/method, based on the source of Membership.GeneratePassword of that works on .NET Core:
public static class Password
{
private static readonly char[] Punctuations = "!##$%^&*()_-+=[{]};:>|./?".ToCharArray();
public static string Generate(int length, int numberOfNonAlphanumericCharacters)
{
if (length < 1 || length > 128)
{
throw new ArgumentException(nameof(length));
}
if (numberOfNonAlphanumericCharacters > length || numberOfNonAlphanumericCharacters < 0)
{
throw new ArgumentException(nameof(numberOfNonAlphanumericCharacters));
}
using (var rng = RandomNumberGenerator.Create())
{
var byteBuffer = new byte[length];
rng.GetBytes(byteBuffer);
var count = 0;
var characterBuffer = new char[length];
for (var iter = 0; iter < length; iter++)
{
var i = byteBuffer[iter] % 87;
if (i < 10)
{
characterBuffer[iter] = (char)('0' + i);
}
else if (i < 36)
{
characterBuffer[iter] = (char)('A' + i - 10);
}
else if (i < 62)
{
characterBuffer[iter] = (char)('a' + i - 36);
}
else
{
characterBuffer[iter] = Punctuations[i - 62];
count++;
}
}
if (count >= numberOfNonAlphanumericCharacters)
{
return new string(characterBuffer);
}
int j;
var rand = new Random();
for (j = 0; j < numberOfNonAlphanumericCharacters - count; j++)
{
int k;
do
{
k = rand.Next(0, length);
}
while (!char.IsLetterOrDigit(characterBuffer[k]));
characterBuffer[k] = Punctuations[rand.Next(0, Punctuations.Length)];
}
return new string(characterBuffer);
}
}
}
I've omitted the do...while loop over the CrossSiteScriptingValidation.IsDangerousString. You can add that back in yourself if you need it.
You use it like this:
var password = Password.Generate(32, 12);
Also, make sure you reference System.Security.Cryptography.Algorithms.
System.Random doesn't provide enough entropy when used for security reasons.
https://cwe.mitre.org/data/definitions/331.html
Why use the C# class System.Random at all instead of System.Security.Cryptography.RandomNumberGenerator?
Please see the example below for a more secure version of #khellang version
public static class Password
{
private static readonly char[] Punctuations = "!##$%^&*()_-+[{]}:>|/?".ToCharArray();
public static string Generate(int length, int numberOfNonAlphanumericCharacters)
{
if (length < 1 || length > 128)
{
throw new ArgumentException("length");
}
if (numberOfNonAlphanumericCharacters > length || numberOfNonAlphanumericCharacters < 0)
{
throw new ArgumentException("numberOfNonAlphanumericCharacters");
}
using (var rng = RandomNumberGenerator.Create())
{
var byteBuffer = new byte[length];
rng.GetBytes(byteBuffer);
var count = 0;
var characterBuffer = new char[length];
for (var iter = 0; iter < length; iter++)
{
var i = byteBuffer[iter] % 87;
if (i < 10)
{
characterBuffer[iter] = (char)('0' + i);
}
else if (i < 36)
{
characterBuffer[iter] = (char)('A' + i - 10);
}
else if (i < 62)
{
characterBuffer[iter] = (char)('a' + i - 36);
}
else
{
characterBuffer[iter] = Punctuations[GetRandomInt(rng, Punctuations.Length)];
count++;
}
}
if (count >= numberOfNonAlphanumericCharacters)
{
return new string(characterBuffer);
}
int j;
for (j = 0; j < numberOfNonAlphanumericCharacters - count; j++)
{
int k;
do
{
k = GetRandomInt(rng, length);
}
while (!char.IsLetterOrDigit(characterBuffer[k]));
characterBuffer[k] = Punctuations[GetRandomInt(rng, Punctuations.Length)];
}
return new string(characterBuffer);
}
}
private static int GetRandomInt(RandomNumberGenerator randomGenerator)
{
var buffer = new byte[4];
randomGenerator.GetBytes(buffer);
return BitConverter.ToInt32(buffer);
}
private static int GetRandomInt(RandomNumberGenerator randomGenerator, int maxInput)
{
return Math.Abs(GetRandomInt(randomGenerator) % maxInput);
}
}

Why the line XXX showing an error saying java.lang.ArrayIndexOutOfBoundsException?

//Firstly I need to create a 2-D array of floating points(randomly generated) and store them in a text file no of rows and columns are user input
import java.io.;
import java.util.;
public class ClaransS {
public static void main(String args[]) throws IOException {
// *********************************************************************
// Variables declaration n-no.of rows k-forget it for now n_o_d-no. of
// columns
// *********************************************************************
int n, k, n_o_d;
// *********************************************************************
// Creating the text file to store data
// *********************************************************************
File f = new File("C:/x/y/clarans.text");
try {
f.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
// *********************************************************************
// Taking user inputs
// *********************************************************************
Scanner userInputScanner = new Scanner(System.in);
System.out.println("Enter the no. of data you want to cluster");
n = userInputScanner.nextInt();
System.out.println(n);
System.out.println("Enter the no. of clusters you want to form");
k = userInputScanner.nextInt();
System.out.println(k);
System.out
.println("Enter the no. of dimensions each data will be in a space of");
n_o_d = userInputScanner.nextInt();
System.out.println(n_o_d);
userInputScanner.close();
// *********************************************************************
// Storing random data in the data-set
// *********************************************************************
double data_set[][] = new double[n][n_o_d];
int count = 1;
int i = 0;
int j = 1;
for (i = 0; i < n; i++) {
data_set[i][0] = count;
for (j = 1; j <= n_o_d; j++) {
//THIS LINE GIVES ERROR
data_set[i][j] = (double) Math.random();//YES THIS ONE XXX
}
count++;
}
for (i = 0; i < n; i++) {
for (j = 0; j <= n_o_d; j++) {
try (PrintWriter out = new PrintWriter(new BufferedWriter(
new FileWriter(f, true)))) {
out.print(data_set[i][j] + "\t");
} catch (IOException e) {
}
}
try (PrintWriter out = new PrintWriter(new BufferedWriter(
new FileWriter(f, true)))) {
out.println();
}
}
}
}
The error is in test condition of for
(j = 1; j <= n_o_d; j++).
Test condition will be j < n_o_d

Resources