public Linearlist mul(Linearlist l1, Linearlist l2) {
Linearlist sum = new Linearlist();
int carry = 0;
long pow = 0;
while (l2.size > 0) {
Linearlist row = new Linearlist();
Linearlist temp1 = l1;
int operand = l2.Delfirst();
for (int i = 0; i < pow; i++) {
row.InsertFirst(0);
}
pow++;
while (temp1.size > 0) {
int result;
result = temp1.Delfirst() * operand + carry;
if (result > 9) {
carry = result / 10;
result = result % 10;
}
row.InsertFirst(result);
}
if (carry > 0) {
row.InsertFirst(carry);
}
sum = sumList(row, sum);
}
return sum;
}
hi this my code and i want to multiply numbers of two list
so write this code and it works for first delete on my second list .
when i debug this code in first time second while work
and next time it doesn't go to second while
where is the problem that temp1.size is not bigger than 0 ???
because when you assign two link list together they get same address
so the assigned link list actually is a first link list .
for assign a link list you must make copy of first link list to second one
Related
I am trying to solve the problem 1438. Longest Continuous Subarray With Absolute Diff Less Than or Equal to Limit. I got the logic but there was a very weird problem due to which I had to pull my hair for more than two hours.
Here is the code :-
class Solution {
public int longestSubarray(int[] nums, int limit) {
Deque<Integer> maxDeque = new LinkedList();
Deque<Integer> minDeque = new LinkedList();
Queue<Integer> queue = new LinkedList();
int maxLength = 1;
for (int i = 0; i < nums.length; i++) {
Integer temp = nums[i];
//int temp = nums[i]; //If I uncomment this line and comment the above line, the code does not work.
queue.offer(temp);
while (!maxDeque.isEmpty() && maxDeque.peekLast() < temp) {
maxDeque.removeLast();
}
while (!minDeque.isEmpty() && minDeque.peekLast() > temp) {
minDeque.removeLast();
}
maxDeque.offerLast(temp);
minDeque.offerLast(temp);
while (maxDeque.peekFirst() - minDeque.peekFirst() > limit) {
if (queue.peek() == maxDeque.peekFirst()) {
maxDeque.pollFirst();
}
if (queue.peek() == minDeque.peekFirst()) {
minDeque.pollFirst();
}
queue.poll();
}
maxLength = Math.max(maxLength, queue.size());
}
return maxLength;
}
}
You see when I put an integer into each of the queues, the code runs fine but when I put an int into the three queues, I get a TLE. So, in the below code, if temp is Integer, the code passes but when temp is int, it gives a TLE. Can someone please explain what is going on ?
Don't use == to compare Integers. It only works when you pre-box temp because of reference equality. Use .equals() instead:
if (queue.peek().equals(maxDeque.peekFirst())) {
maxDeque.pollFirst();
}
if (queue.peek().equals(minDeque.peekFirst())) {
minDeque.pollFirst();
}
So the problem that I'm trying to solve is where you have an array of stock prices where each position is a different stock price. Now the problem is writing an algorithm to calculate the span of the stock which basically means each i position contains the number of previous stocks that were either less than or equal to the current stock. This is what I have right now:
public static int[] stockSpan(int[] stock) {
int[] span = new int[stock.length];
for (int i = 0; i < stock.length; i++) {
int index = i - 1;
span[i] = 1;
while (index >= 0 && stock[index] <= stock[i]) {
span[i] += span[index];
index -= span[index];
}
}
return span;
}
What I'm trying to do now is use stacks to try and improve the running time of this to O(n). The thing is I'm more used to using for loops and arrays to solve this problem so how do I implement stacks into this algorithm?
Solution Source
Stock Span problem: For a given array P of stock prices the stock span is the maximum number of consecutive days the price of the stock has been less than or equal to its price on day i. This can be solved efficiently using a stack.
public static int[] computeSpan(int[] P) {
int length = P.length;
int[] S = new int[P.length];
MyStack<Integer> myStack = new MyStack<>(length);
int h = 0;
for (int i = 0; i < length; i++) {
h = 0;
while (!myStack.isEmpty()) {
if (P[i] >= P[myStack.top()]) {
myStack.pop();
} else {
break;
}
}
h = myStack.isEmpty() ? -1 : myStack.top();
S[i] = i - h;
myStack.push(i);
}
return S;
}
Please go through the link for solution reference.
Try this solution :
public static Map<Integer, Integer> getStockSpan(int[] prices) {
Map<Integer, Integer> stockSpan = new HashMap<>();
Stack<Integer> span = new Stack<>();
for (int price : prices) {
int count = 1;
while (!span.isEmpty() && price >= span.peek()) {
count += stockSpan.get(span.pop());
}
span.push(price);
stockSpan.put(price, count);
}
return stockSpan;
}
here is my code in C++ using stack library
#include <iostream>
#include <stack>
using namespace std;
void CalculateSpan(int a[],int n,int S[]){
stack<int> st;
//create the stack
int i;
st.push(0); //pushed first element of ARRAY to stack
//as there is nothing to the left of initial element set its span as 1 to default
S[0]=1;
for(i=1;i<n;i++){
//start looping from index 1
//basically we are comparing initial element with all other element
//now initially if top of stack is less than ith index of array then just pop
while(!st.empty()&&a[st.top()]<=a[i])
st.pop();
if(st.empty())
S[i]=i+1;
else
//to get span if ith index greater then top then just substract ith from top index and push the ith index
S[i]=i-st.top();
st.push(i);
}
}
void printa(int arr[],int n){
int i;
for(i=0;i<n;i++){
cout<<arr[i];
}
}
int main()
{
int a[10],S[10];
int n,i;
cout<<"Enter the size of the element you want";
cin>>n;
cout<<"\nEnter the number of elements you want\n";
for(i=0;i<n;i++){
cin>>a[i];
}
CalculateSpan(a,n,S);
printa(S,n);
}
perform these operation n times :
1) two get the value u need to calculate
res = i-R+1
where i is current index and R is the index popped from stack
2) do following
i) if stack is not empty and current element is >= to the element at top index then do following
while stack is not empty and current element is >= to the a[top] do pop()
ii) push the current index to the stack and calculate the value
int *a, *res;
a = new int[n];
res = new int[n];
stack<int>S;
for(int i=0;i<n;i++){
int top = i;
if(!S.empty() && a[S.top()]<=a[i]) {
while(!S.empty() && a[S.top()]<=a[i]){
top = S.top();
S.pop();
}
S.push(top);
}
S.push(i);
res[i] = i-top+1;
}
I have added few number into the arraylist . I would want to find the certain value from it.Example i have 4,4,9,9,18. I would like to find the value of 26. If 26 > largest value in the list it will display 18 and if value is 17 it will display 9, and if value is 5 it will display 4. Also is there another method to implement this search because liner search might be slow.
search value 26
[4,4,9,9,18] display 18
[20,20,29,29,4] display 20
[28,28,28,1,10] display 28
if you have this list and search 26, it will output the first element. because the first element is <= than the value being search.
but current output is
Value of value2 : 9
public class Arraylist {
public static ArrayList<Integer> aList;
public static void main(String[] args) {
aList = new ArrayList<Integer>();
aList.add(4);
aList.add(4);
aList.add(9);
aList.add(9);
aList.add(18);
int value = 26;
int value2 = 0;
for (int i = 0; i < aList.size(); i++) {
if (aList.get(i) <= value) {
if (i + 1 < aList.size()) {
value2 = aList.get(i);
} else if(i > aList.size()) {
value2 = aList.get(i);
}
}
}
System.out.println("Value of value2 : " + value2);
}
}
I have written the code using an array. You can easily adopt it to ArrayList
int a[] = {28,28,28,1,10};
// int a[] = {20,20,29,29,4}; // other input of yours
// int a[] = {4,4,9,9,18};
int x = 26;
int liVal = -1;
for(int i=0; i<a.length;i++)
if(x < a[i]) // if we met a value > x
{
if(liVal==-1) // if we could not find any largest value smaller than x
liVal = a[i]; // return the value > x
break;
}
else if(x > a[i]) // find the largest value smaller than x,
{
if(liVal < a[i])
liVal = a[i];
}
System.out.println(liVal);
A trivial and un-optimized version:
int value = 26 // or whatever parameter you get
int retVal = Integer.MIN_VALUE;
for (int i : list) {
if (i <= value && i > retVal) {
retVal = i;
}
}
return retVal;
If the array is sorted you can use a variant of binary search.
see http://en.wikipedia.org/wiki/Binary_search_algorithm
Once you sort the list, binarySearch in Collections will do the trick:
Collections.sort(aList)
int index = Collections.binarySearch(aList)
If index is nonnegative, the number was found in the list, and index is the position. If it is negative, it wasn't found, but index indicates where it would be if it were in the list.
And with O(log n) runtime for the search.
If I understand correctly, you want to find the biggest number in your array that is smaller or equal to value. I would do it like this:
for (int i = 0; i < aList.size(); i++) {
if ( aList.get(i) <= value && aList.get(i) > value2) {
value2 = aList.get(i);
}
}
Also in your example, you do value2 = 0. This is ok if you can guarante that the array only contains positive values. Otherwise it would be better to use value2 = Integer.MIN_VALUE.
Finally, this code assume that the array is not guarantied to be sorted and that you will only need to search it once. Otherwise, a binary search could be more performant. Other answers on this question already show how to accomplish that.
According to the OP's comments:
The list isn't sorted
if value < min return min
if value > max return max
if min <= value <= max return nearest val <= value
public static int findValue(List<Integer> list, int value){
int min = Integer.MAX_VALUE, nearest = Integer.MIN_VALUE;
for(Integer v : list){
if(v == value)
return value;
if(v > nearest && v < value)
nearest = v;
if(v < min)
min = v;
}
return value < min ? min : nearest;
}
As a side note, you don't need to keep track of the max because nearest = max if value > max(list).
I have a list and I'd like to get the values at i-1, i and i+1 positions. When i is the first or the last index, it would throw an IndexOutOfBoundsException. To prevent that, I would write a few if-statements and hardcode it like that:
if (i == 0){
a = list.get(list.size()-1);
b = list.get(0);
c = list.get(1);
} else if (i == list.size()-1){
a = list.get(i-1);
b = list.get(i);
c = list.get(0);
} else {
a = list.get(i-1);
b = list.get(i);
c = list.get(i+1);
}
I find this way is a littlebit static. Let's say I want to get n entries from the list in this way, how would you do that?
You can use (i-1+list.size()) % list.size() and (i+1) % list.size().
This will also handle lists of length 1.
Heavier options:
Write a method
<T> T get(List<T> list, int i)
{
i %= list.size();
return list.get(i >= 0 ? i : i + list.size());
}
Subclass and override get()
Make a wrapper class which wraps around indices
You could use the ternary operator to shorten the code a little, and factor out the get calls to shorten the code further.
int prev, i, next;
//start loop here
prev = (i == 0 ? list.size()-1 : i-1);
next = (i == list.size()-1 ? 0 : i+1);
a = list.get(prev);
b = list.get(i);
c = list.get(next);
// end loop here
You will have to handle small lists, (size() <= 2) to stop repeating elements.
Why you can't just iterate with foreach and reassign old values like this:
List<Integer> list = Arrays.asList(1, 5, 7, 3, 4);
int n = 3; // how much entries we take
int a = 0, b = 0, c;
for (int i = 0; i < n; i++) {
c = b;
b = a;
a = list.get(i);
// do some stuff
}
I have source array, and I want to generate new array from the source array by removing a specified number of elements from the source array, I want the elements in the new array to cover as much as possible elements from the source array (the new elements are uniformly distributed over the source array) and keeping the first and last elements the same (if any).
I tried this :
public static void printArr(float[] arr)
{
for (int i = 0; i < arr.length; i++)
System.out.println("arr[" + i + "]=" + arr[i]);
}
public static float[] removeElements(float[] inputArr , int numberOfElementToDelete)
{
float [] new_arr = new float[inputArr.length - numberOfElementToDelete];
int f = (inputArr.length ) / numberOfElementToDelete;
System.out.println("f=" + f);
if(f == 1)
{
f = 2;
System.out.println("f=" + f);
}
int j = 1 ;
for (int i = 1; i < inputArr.length ; i++)
{
if( (i + 1) % f != 0)
{
System.out.println("i=" + i + " j= " + j);
if(j < new_arr.length)
{
new_arr[j] = inputArr[i];
j++;
}
}
}
new_arr[0] = inputArr[0];
new_arr[new_arr.length - 1] = inputArr[inputArr.length - 1];
return new_arr;
}
public static void main(String[] args)
{
float [] a = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
a = removeElements(a, 6);
printArr(a);
}
I have made a test for(removeElements(a, 5) and removeElements(a, 4) and removeElements(a, 3)) but removeElements(a, 6); gave :
arr[0]=1.0
arr[1]=3.0
arr[2]=5.0
arr[3]=7.0
arr[4]=9.0
arr[5]=11.0
arr[6]=13.0
arr[7]=15.0
arr[8]=0.0
arr[9]=16.0
the problem is (arr[8]=0.0) it must take a value ..
How to solve this? is there any code that can remove a specified number of elements (and keep the elements distributed over the source array without generating zero in some elements)?
EDIT :
examples :
removeElements(a, 1) ==> remove one element from the middle (7) {1,2,3,4,5,6,7,9,10,11,12,13,14,15,16}
removeElements(a, 2) ==> remove two elements at indexes (4,19) or (5,10) or (4,10) (no problem)
removeElements(a, 3) ==> remove three elements at indexes (4,9,14) or (4,10, 15) or(no problem also)
removeElements(a, 4) ==> remove four elements at indexes (3,7,11 , 15) or ( 3 ,7,11,14) for example ..
what I want is if I draw the values in the source array on (chart on Excel for example) and I draw the values from the new array , I must get the same line (or close to it).
I think the main problem in your code is that you are binding the selection to
(inputArr.length ) / numberOfElementToDelete
This way you are not considering the first and the last elements that you don't want to remove.
An example:
if you have an array of 16 elements and you want to delete 6 elements it means that the final array will have 10 elements but, since the first and the last are fixed, you'll have to select 8 elements out of the remaining 14. This means you'll have to select 8/14 (0,57) elements from the array (not considering the first and the last).
This means that you can initialize a counter to zero, scan the array starting from the second and sum the value of the fraction to the counter, when the value of the counter reach a new integer number (ex. at the third element the counter will reach 1,14) you'll have an element to pick and put to the new array.
So, you can do something like this (pseudocode):
int newLength = originalLength - toDelete;
int toChoose = newLength - 2;
double fraction = toChoose / (originalLength -2)
double counter = 0;
int threshold = 1;
int newArrayIndex = 1;
for(int i = 1; i < originalLength-1; i++){
**counter += fraction;**
if(integerValueOf(counter) == threshold){
newArray[newArrayIndex] = originalArray[i];
threshold++;
**newArrayIndex++;**
}
}
newArray[0] = originalArray[0];
newArray[newArray.length-1] = originalArray[originalArray.length-1];
You should check for the particular cases like originalArray of length 1 or removal of all the elements but I think it should work.
EDIT
Here is a Java implementation (written on the fly so I didn't check for nulls etc.)
public class Test {
public static void main(String[] args){
int[] testArray = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
int[] newArray = remove(testArray, 6);
for(int i = 0; i < newArray.length; i++){
System.out.print(newArray[i]+" ");
}
}
public static int[] remove(int[] originalArray, int toDelete){
if(toDelete == originalArray.length){
//avoid the removal of all the elements, save at least first and last
toDelete = originalArray.length-2;
}
int originalLength = originalArray.length;
int newLength = originalLength - toDelete;
int toChoose = newLength - 2;
int[] newArray = new int[newLength];
double fraction = ((double)toChoose) / ((double)originalLength -2);
double counter = 0;
int threshold = 1;
int newArrayIndex = 1;
for(int i = 1; i < originalLength-1; i++){
counter += fraction;
if(((int)counter) == threshold ||
//condition added to cope with x.99999999999999999... cases
(i == originalLength-2 && newArrayIndex == newLength-2)){
newArray[newArrayIndex] = originalArray[i];
threshold++;
newArrayIndex++;
}
}
newArray[0] = originalArray[0];
newArray[newArray.length-1] = originalArray[originalArray.length-1];
return newArray;
}
}
Why cant you just initialize i=0
for (int i = 0; i < inputArr.length; i++) {
if ((i + 1) % f != 0) {
Following is the output:
arr[0]=1.0
arr[1]=1.0
arr[2]=3.0
arr[3]=5.0
arr[4]=7.0
arr[5]=9.0
arr[6]=11.0
arr[7]=13.0
arr[8]=15.0
arr[9]=16.0
This is Reservoir sampling if I understand it right i.e from a large array, create a small array by randomly choosing.