I need to write a method for a linked list class that:
Print the contents of every "nth" node in the list. Obtain the "n" from the user, ensure it is
greater than 0.
How would i go about doing this?
public void nthNode (int n) {
if (n <= 0) {
System.out.println("error");
} else {
//bla
}
}
public void nthNode (int n) {
if (n <= 0) {
System.out.println("error");
} else {
for (int i = 0; i < size(); i += n) {
//LinkedList#get(i);
}
}
}
Iterate over every element in the list. If the index of the current item is evenly divisible by n then print the element. You can check for even divisibility by using the modulus operator (% in Java)
You main motive is to print the data of nodes when the counter will be a multiple of n.
so instead of checking the mod on data, u need to do it on counter and have the mod check with n.
Iterating over the link list (using say curr pointer) using while loop. Check for condition curr.next!=null. initialize count to 0. While iterating count the number of nodes traversed till now. If the (count == n), then print the node data and initialize count to 0.
Assuming you have a node class of some sort:
public void nthNode( int n ){
if( n <= 0 ){
System.out.println( "error" );
} else {
Node e = new Node();
e = head;
int count = 0;
while( e != null ){
if( count == n ){
//do stuff
break;
}
e = e.next;
cout++;
}
}
Sorry kinda sloppy but that's the gist.
Related
Long story short, I'm supposed to make a code that inserts, deletes, searches for and prints numbers in a skip list with the first node being negative infinity and the last node being positive infinity (-inf > (...) > inf). I called my search function from my insert function to find a spot to insert any new nodes (only after the third node has been inserted) and I initialize or reference my nodes outside the main function rather than inside of it (although I'm debating on whether or not I should do the latter instead). However one of my functions may be stuck in a loop.
static Node search(double item, double max) {
Node head2 = head;
head2 = Start(head2, max);
//starts at the first highest node in the skiplist
//{... } //find a specific node in a skiplist
return head2;
}
//find first highest node for the search function
static Node Start(Node head2, double max) {
System.out.println(head.key + " " + head.level);
Node s = new Node();
if (head2.max < max) {
s = Start(head2.next, max);
return s;
}
else if (head2.max >= max && head2.inf == false) {
if (head2.level < head2.max) {
s = Start(head2.up, max);
return s;
}
else if (head2.level == head2.max) {
s = head;
return s;
}
}
return s;
}
The start function is called from the search function (called in order of main > double insert > Node search > Node start) and it is supposed to find the first node of the highest level. Once it does so, It returns that node to the search function so it can start it's search from there. But when called, it simply goes blank and nothing happens despite continuing to run. When I put in a print function to determine the problem, it simply prints the first node's key and 1st level and goes blank from there. UPDATE: I've learned that the function is able to find the node but it can't return it via recursion. I would like to find a way to fix that.
The problem was actually in my search function.
for(j = max; j >= 1; j--) {
while(head2.next != last && head2.key != item && i == 0) {
if(item > head2.key && head2.next != last) {
head2 = head2.next;
}
else if(item < head2.key || head2.next == last) {
head2 = head2.prev;
i = 1;
}
}
(...)}
this was the function that kept looping so I had to change the statement for while by having it say this instead
while(head2.next != last && head2.key < item && head2.inf != true && i == 0)
I want to count how many leaf node in a trie structure by counting how many words there are in the trie, but my code is not updating the counting value, instead it always reset back to 0.
int num = 0;
public int countLeafNodes() {
for (char c : children.keySet()) {
Trie node = children.get(c);
System.out.println(c);
if (node.isWord) {
num++;
System.out.println(num);
}
node.countLeafNodes();
}
return num;
}
You are ignoring the value returned by the recursive call (node.countLeafNodes()).
Try :
public int countLeafNodes()
{
int num = 0;
for (char c : children.keySet()) {
Trie node = children.get(c);
System.out.println(c);
if (node.isWord) {
num++;
System.out.println(num);
}
num += node.countLeafNodes();
}
return num;
}
So it appears that the issue is that when you return from your recursion you are not taking in to account the values being returned. What I mean is that when counting the leaf nodes in the children you are not adding that total to the parents. If that is the issue you would just need to change
node.countLeafNodes();
to
num += node.countLeafNodes();
I have the array {1,2,3,4,4,4,5}
I want my function return index of 4.
for example : 4 found at location 4,5,6
public void binarySearch(int value){
sort(); // sorting the array
int index=-1;
int lower=0;
int upper=count-1;
while(lower<=upper){
int middle=(lower+upper)/2;
if(value==array[middle]){
index=middle;
System.out.println(value+ " found at location "+(index+1));
break;
}
else if(value<array[middle]){
upper=middle-1;
}
else lower=middle+1;
}
}
It's not too hard. We know that because the list is sorted, all of our indexes are going to be contiguous (next to one another). So once we've found one, we just have to traverse the list in both directions to find out what other indexes also match.
public static void binarySearch(int value){
sort();
int index = -1;
int lower = 0;
int upper = array.length - 1;
while(lower <= upper){
// The same as your code
}
// Create a list of indexes
final List<Integer> indexes = new LinkedList<>();
// Add the one we already found
indexes.add(index);
// Iterate upwards until we hit the end or a different value
int current = index + 1;
while (current < array.length && array[current] == value)
{
indexes.add(current);
current++;
}
// Iterate downwards until we hit the start or a different value
current = index - 1;
while (current >= 0 && array[current] == value)
{
indexes.add(current);
current--;
}
// Sort the indexes (do we care?)
Collections.sort(indexes);
for (int idx : indexes)
{
System.out.println(value + " found at " + (idx + 1));
}
}
Bear in mind that what you have implemented is already a binary search. The extra code to find additional matching indexes would not fall under the usual definition of a binary search.
Okay guys thanks for all the help! Special thanks to #pjs for giving me an idea of how to do it. Here is my new code, but for some reason it won't reach one of the base cases. Sorry if I deleted the old code, this is the first time I posted here and I am not sure if I should answer my own question with the new code.
//initialized int start = 0
//initialized int end = length of the array
//here goes the constructor
public boolean kPairSum(Integer k) {
if (sortedIntegerArray.length < 2) { //if array is less than two return false
return false;
}
else if (start == end) { //once the start and the end meets. This is the base case that doesn't seem to work for me.
return false;
}
else {
int currentStart = sortedIntegerArray[start]; //get first int in the array
int currentEnd = sortedIntegerArray[end-1]; //get the very last int in the array
int sum = currentStart + currentEnd; //get the sum
if (k.equals(sum)) { //compare sum and k if equal
return true;
}
else if (sum <k) { //if sum is less than k then increment value of start
start++;
return kPairSum(k);
}
else if (sum > k) { //if sum is greater than k then it decrements value of end
end--;
return kPairSum(k);
}
else { //not sure if this is right, should I just get rid of the else if statement for sum > k and change it to just an else? I wrote this down cause it has to return a type of boolean.
return kPairSum(k);
}
}
Your array is called sortedIntegerArray, but you don't seem to be leveraging that fact.
Start by summing the two ends of the array. If the sum is smaller than k, one of the two elements of the sum has to be larger. You can only get a larger value by incrementing the lower index because the elements are ordered. Similarly, if the sum is larger than k, one of the two elements has to be smaller, so you need to decrement the upper index. In either case, the structure of the problem is the same but you're now operating on a subset of the array specified by which of the indices you incremented/decremented. Base cases are that you found two values which sum to k, or that the indices have met somewhere. The recursion should leap out at you. Since each recursive call either increments or decrements a boundary index until they meet in the middle, it's O(n).
Your recursive call is never invokes:
if (sum == k) { //compare to given k
return true;
} else if (xx == sortedIntegerArray.length-1 || sum != k) {
return false;
}
Note that you basically have two choices: sum==k, and then - return true, or sum!=k - and then return false. The recursive invokation is not reachable.
An O(n) (average case) solution can be achieved using a hash table. The idea is to add each element to the hash table while iterating, and check if there is an existing element that completes to k.
for each element e in arr:
if e is in table:
return true
table.add(k-e)
return false //no pair was found that sums to k
A recursive solution that checks all pairs, is basically brute force that is similar to a nested for loop.
//i is the index we are now checking, b is a boolean indicating we have already reduced one element
kSum(k,i,b):
if i == arr.length
return false
if b == true && k == 0:
return true
if b == false:
return kSum(k-arr[i],i+1,true) || kSum(k,i+1,false)
else:
return kSum(k,i+1,b)
I have two implementations here:
One I initially got to work and with Amit answer, I improved it further. It also prints/return the indices that make up the sum. works with both sorted and unsorted array in O(n). ofcourse, this is not recursive.
public static void sumArray2(int[] arr, int sum){
Map <Integer, Integer> map = new HashMap<>();
for (int i=0; i < arr.length;i++){
map.put(arr[i], i);
}
for (int i =0; i < arr.length;i++){
int diff = sum-arr[i];
if (map.containsKey(diff) && i!=map.get(diff)) {
System.out.printf("The two indices are %s and %s%n ",i,map.get(diff));
return ;
}
}
System.out.printf("The sum:%s cannot be formed with given array:%s",sum,Arrays.toString(arr));
return ;
}
//returns a boolean if sum could be formed.
public static boolean sumArray3(int[] arr, int sum){
Map <Integer, Integer> map = new HashMap<>();
for (int i =0; i < arr.length;i++){
int diff = sum-arr[i];
if (map.containsKey(arr[i])) {
System.out.printf("The two indices are %s and %s%n ",i,map.get(arr[i]));
return true;
}
map.put(diff,i);
}
System.out.printf("The sum:%s cannot be formed with given array:%s",sum,Arrays.toString(arr));
return false;
}
don't know how to add formatted comment, so here is enhanced version, than Amit provided, works with O(n) :)
def check(source, need):
target = [need-i for i in source]
target.reverse()
i = 0
j = 0
# walk thru lists same "merge" to find a match
for i in xrange(0, len(source)):
while j < len(target) and source[i] > target[j]:
j=j+1
if i != len(source)-j-1 and j < len(target) and source[i] == target[j]:
return True
return False
There is a challenge problem in my compsci UIL class to use tail recursion to get a list of binomial coefficients for a given number . I think I am pretty close but I am having a hard time with base cases.
Following is my Code :
public static Cons binomial(int n)
{
return binomialb(n, null, 1);
}
public static Cons binomialb(int n, Cons last, int power)
{
if(n == power || n < 0)
{
return cons(1, null);
}
else if(last == null)
{
last = cons(1, cons(1, null));
return binomialb(n-1, last, power);
}
else
{
Cons lst = cons(1, null);
while(rest(last)!=null)
{
lst = cons((Integer)first(last)+(Integer)first(rest(last)), lst);
last = rest(last);
}
return binomialb(n-1,lst,power);
}
}
Right now I just get a list of (1).....
Your recursive call is always binomialb(n-1,something,power), so the only things that change are the first parameter, n, and the list. Your initial call has power = 1, so that will remain forever so. Now your first condition is
if (n == power || n < 0) {
return cons(1,null);
}
If you call it with n > 1 initially, the calls become binomialb(n-k,...,1) for k = 1, ..., n-1. Finally the call is binomialb(1,lotsOfWastedWork,1) which will happily return cons(1,null). If you initially call it with n < 1, the n < 0 will make it return the same after at most one recursive call, n = 1 immediately returns cons(1,null).
Whenever last is not null in a call, you should use it.