I am trying to do a programming problem a day on leetcode to improve my programming and am having issues adding to a LinkedList in the problem below. I was wondering if anyone could give me some pointers. I know my answer isn't the most efficient, I just wanted to start somewhere and work myself up. Everything within the method is stuff I did so far. I really appreciate any help.
///
You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
Here's a picture with an example for a possible output:
https://imgur.com/a/g9rlb
You may assume the two numbers do not contain any leading zero, except the number 0 itself.
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode l3 = new ListNode(-1);
ListNode curr = new ListNode(-1);
ListNode newNode = new ListNode(-1);
// Take numbers from linkedList and store in strings
String s1 = "";
String s2 = "";
// String values after being reveresed in the right direction.
String sR1 = "";
String sR2 = "";
while(l1 != null) {
s1 += l1.val;
l1 = l1.next;
}
while(l2 != null) {
s2 += l2.val;
l2 = l2.next;
}
//check
System.out.println(s1);
System.out.println(s2);
//reverse the string;
for(int i = s1.length()-1; i >= 0; i--) {
sR1 += s1.charAt(i);
}
for(int j = s2.length()-1; j >= 0; j--) {
sR2 += s2.charAt(j);
}
//Adding the numbers together to get the final value.
int n3 = Integer.parseInt(sR1) + Integer.parseInt(sR2);
//Converting ints to string so i can parse them into characters that will eventually be parsed into an int to return back to the LinkedList
String fin = Integer.toString(n3);
System.out.println(fin);
//adding the values to my final linked list that i'd be returning here. This is the part that isn't working.
for(int i = 0; i < fin.length()-1; i++){
String s = String.valueOf(fin.charAt(i));
int num = Integer.parseInt(s);
newNode = new ListNode(num);
if(l3.val == -1) {
l3 = newNode;
}
else {
curr = l3;
while(curr.next != null){
curr = curr.next;
}
curr.val = num;
}
}
return l3;
}
Maybe something like this? The concept here is straight forward.
The requirement is to reverse the nodes and adding them. Which means you just need to choose the right data structure to meet this requirement, which provides you last in first out? Stack. Now that you have you data in a stack just pop the items from the stack and add it up and get your expected result.
There are many ways to solve this, Using an ArrayList, using LinkedList, or plain old arrays, but try to correlate the problem with a known data structure and addressing it that way would give you meaningful output consistently. I could have just pointed you to the concept but having this code will help you think on how to address a specific problem based on the user requirement. Cheers, hope it helps.
import java.util.Scanner;
import java.util.Stack;
public class AddTuple {
public static void main(String[] args) {
Stack<Integer> leftTuple = new Stack<Integer>();
Stack<Integer> rightTuple = new Stack<Integer>();
populateTuple(leftTuple, rightTuple, 3);
Stack<Integer> result = addTuples(leftTuple, rightTuple);
System.out.print("Output: {");
int i = 0;
while (!result.isEmpty()) {
if (i != 0) {
System.out.print(", ");
}
System.out.print(result.pop());
i++;
}
System.out.println("}");
}
private static void populateTuple(Stack<Integer> leftTuple, Stack<Integer> rightTuple, int count) {
Scanner scanner = new Scanner(System.in);
try {
System.out.print("Input: ");
String input = scanner.nextLine();
if (input == null || !input.contains("+") || !input.contains("{")) {
throw new RuntimeException("Usage: {x,y,z} + {a,b,c}");
}
String[] operandSplit = input.split("\\+");
String left = operandSplit[0].trim();
String right = operandSplit[1].trim();
left = left.replaceAll("\\{", "");
left = left.replaceAll("\\}", "");
right = right.replaceAll("\\{", "");
right = right.replaceAll("\\}", "");
String[] leftSplit = left.split(",");
String[] rightSplit = right.split(",");
for (int i = 0; i < leftSplit.length; i++) {
leftTuple.push(Integer.parseInt(leftSplit[i].trim()));
}
for (int i = 0; i < rightSplit.length; i++) {
rightTuple.push(Integer.parseInt(rightSplit[i].trim()));
}
} finally {
scanner.close();
}
}
private static Stack<Integer> addTuples(Stack<Integer> leftTuple, Stack<Integer> rightTuple) {
Stack<Integer> result = new Stack<Integer>();
int carryForward = 0;
while (!leftTuple.isEmpty()) {
int addition = leftTuple.pop() + rightTuple.pop() + carryForward;
if (addition > 9) {
carryForward = 1;
addition = 10 - addition;
}
result.push(addition);
}
return result;
}
}
Related
I need to create all possible strings from a 2d-array so that the first character comes from charArray[0], the second character comes from charArray[1]...and the final character comes from the charArray[keyLength-1].
Example:
input:
char[][] charArray =
{{'m','M','L','S','X'}
{'e','E','o','N','Z'}
{'o','G','F','r','Y'}
{'D','H','I','J','w'}};
output:
{meoD, meoH, meoI,..., XZYJ, XZYw} //in an Array or ArrayList
I had a working solution that builts a tree with each character in charArray[0] as a root and it did a depth first string construction, but the JVM ran out of memory for charArray lengths less than 12. I would normally take an iterative approach, but the charArray length (i.e. key string length) is decided at runtime and I would like to find a more complete solution than writing a switch statement on the key string length and manually writing out loops for a finite number of key string lengths.
I've been stuck on this small section of my program for longer than I'd like to admit, so any help would be greatly appreciated!
Here is how it can be solved:
import java.util.ArrayList;
import java.util.List;
public class Arrays2D {
public static void main(String[] args) {
//input keys
String[][] charArray =
{{"m","M","L","S","X"},
{"e","E","o","N","Z"},
{"o","G","F","r","Y"},
{"D","H","I","J","w"}};
//print output
System.out.println(findCombinations(charArray));
}
private static List<String> findCombinations(String[][] charArray) {
List<String> prev = null;
for (int i = 0; i < charArray.length; i++) {
List<String> curr = new ArrayList<String>();
for (int j = 0; j < charArray[i].length; j++) {
if (i + 1 < charArray.length) {
for (int l = 0; l < charArray[i+1].length; l++) {
String s = charArray[i][j] + charArray[i + 1][l];
curr.add(s);
}
}
}
if (prev != null && !curr.isEmpty()) {
prev = join(prev, curr);
}
if (prev == null)
prev = curr;
}
return prev;
}
public static List<String> join(List<String> p, List<String> q) {
List<String> join = new ArrayList<String>();
for (String st1 : p) {
for (String st2 : q) {
if (st1.substring(st1.length() - 1).equals(st2.substring(0, 1))) {
String s = st1 + st2;
s = s.replaceFirst(st1.substring(st1.length() - 1), "");
join.add(s);
}
}
}
return join;
}
}
I have checked and it correctly generating the combinations. You can run and see the output.
So the problem I'm trying to solve this problem given a string, find the length of the longest substring without repeating characters. I'm aware of the HashMap based solution, but that fails in case of overlapping substrings.Here's my code.
public static int lengthOfLongestSubstring(String s) {
Deque<Character> primary = new ArrayDeque<>();
Deque<Character> secondary = new ArrayDeque<>();
for (int i = 0; i < s.length() ; i++) {
char c = s.charAt(i);
if(primary.contains(c)){
while(primary.peek() != c){
secondary.offerLast(primary.poll());
}
secondary.offerFirst(c);
primary = secondary;
secondary.clear();
}else{
primary.offerFirst(c);
}
}
return primary.size();
}
This fails at the line where I do primary = secondary otherwise I think I'm doing it right logically.
To test the correctness I'm using the string dvdf
Can someone help me understand why this is not working.
I am wondering this:
primary = secondary;
secondary.clear();
It's assignment by reference. You set primary and secondary to point to the same data and clear it. Is that your intention?
What about this:
public static int lengthOfLongestSubstring(String s) {
Deque<Character> primary = new ArrayDeque<>();
Deque<Character> secondary = new ArrayDeque<>();
Deque<Character> longest = new ArrayDeque<>();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (primary.contains(c)) {
// Store longest
if (primary.size() > longest.size()) {
longest = new ArrayDeque<>(primary);
}
while (primary.peek() != c) {
secondary.offerLast(primary.poll());
}
secondary.offerFirst(c);
primary = secondary;
secondary = new ArrayDeque<>(); // Altered
} else {
primary.offerFirst(c);
}
}
// Also check at end of line.
if (primary.size() > longest.size()) {
longest = primary;
}
return longest.size();
}
OUTPUT
dvdf => 3
dvdfvadv => 4
EDIT
Your logic is right. I just altered one line.
EDIT
Keep track of the longest.
May not be exact answer you were looking. Try to avoid using ArrayDeque in a multi threaded env as it is not thread safe.
Go through this link::
Find longest substring without repeating characters
this returns a string. you can use .length() method and find the length as you require.
Hope it helps.
You can try this:
public class LongestSubstring {
public static void main(String [] args){
System.out.println(longestSub("abcdefgghij"));
//prints 7 abcdefg g is repeated character
}
public static int longestSub(String s) {
if(s==null)
return 0;
boolean[] flag = new boolean[256];
int result = 0;
int start = 0;
char[] arr = s.toCharArray();
for (int i = 0; i < arr.length; i++) {
char current = arr[i];
if (flag[current]) {
result = Math.max(result, i - start);
// the loop update the new start point and reset flag array
for (int k = start; k < i; k++) {
if (arr[k] == current) {
start = k + 1;
break;
}
flag[arr[k]] = false;
}
} else {
flag[current] = true;
}
}
result = Math.max(arr.length - start, result);
return result;
}
}
/*C++ program to print the largest substring in a string without repetation of character.
eg. given string :- abcabbabcd
largest substring possible without repetition of character is abcd.*/
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str,str1;
int max =0;
string finalstr;
vector<string> str2;
cin>>str;
int len = str.length();
for(int i=0;i<len;i++)
{
if(str1.find(str[i]) != std::string::npos)
{
str2.push_back(str1);
char p = str[i];
str1 = "";
i--;
while(p!=str[i])
i--;
}
else
str1.append(str,i,1);
}
str2.push_back(str1);
for(int i=0;i<str2.size();i++)
{
if(max<str2[i].length()){
max = str2[i].length();
finalstr = str2[i];
}
}
cout<<finalstr<<endl;
cout<<finalstr.length()<<endl;
}
I've been working for hours trying to order a linked list of strings alphabetically (dictionary-like). The given string is lowercase only.
For example, input of: "hello my name is albert" will be sorted in the list as: Node 1: albert,
Node 2: hello,
Node 3: is,
etc..
My code so far reads a string like the example above and insert it as nodes - unordered.
I've searched in the web for ways to sort a linked list alphabetically with good performance, and I found Merge Sort can be usefull.
I've changed the merge sort to work for string using compareTo() but my code returns nullPointerException error in the following line:
if(firstList._word.compareTo(secondList._word) < 0){
I'm looking for help to fix the following code or another way for sorting a linked list alphabetically (without Collection.sort)
My full code is (after trying to add the merge sort to work with my code):
public class TextList
{
public WordNode _head;
public TextList()
{
_head = null;
}
public TextList (String text)
{
this._head = new WordNode();
int lastIndex = 0;
boolean foundSpace = false;
String newString;
WordNode prev,next;
if (text.length() == 0) {
this._head._word = null;
this._head._next = null;
}
else {
for (int i=0;i<text.length();i++)
{
if (text.charAt(i) == ' ') {
newString = text.substring(lastIndex,i);
insertNode(newString);
// Update indexes
lastIndex = i;
// set to true when the string has a space
foundSpace = true;
}
}
if (!foundSpace) {
//If we didnt find any space, set the given word
_head.setWord(text);
_head.setNext(null);
}
else {
//Insert last word
String lastString = text.substring(lastIndex,text.length());
WordNode lastNode = new WordNode(_head._word,_head._next);
_head.setNext(new WordNode(lastString,lastNode));
}
sortList(_head);
}
}
private void insertNode(String word)
{
//Create a new node and put the curret node in it
WordNode newWord = new WordNode(_head._word,_head.getNext());
//Set the new information in the head
_head._word = word;
_head.setNext(newWord);
}
private WordNode sortList(WordNode start) {
if (start == null || start._next == null) return start;
WordNode fast = start;
WordNode slow = start;
// get in middle of the list :
while (fast._next!= null && fast._next._next !=null){
slow = slow._next; fast = fast._next._next;
}
fast = slow._next;
slow._next=null;
return mergeSortedList(sortList(start),sortList(fast));
}
private WordNode mergeSortedList(WordNode firstList,WordNode secondList){
WordNode returnNode = new WordNode("",null);
WordNode trackingPointer = returnNode;
while(firstList!=null && secondList!=null){
if(firstList._word.compareTo(secondList._word) < 0){
trackingPointer._next = firstList; firstList=firstList._next;
}
else {
trackingPointer._next = secondList; secondList=secondList._next
;}
trackingPointer = trackingPointer._next;
}
if (firstList!=null) trackingPointer._next = firstList;
else if (secondList!=null) trackingPointer._next = secondList;
return returnNode._next;
}
public String toString() {
String result = "";
while(_head.getNext() != null){
_head = _head.getNext();
result += _head._word + ", ";
}
return "List: " + result;
}
public static void main(String[] args) {
TextList str = new TextList("a b c d e a b");
System.out.println(str.toString());
}
}
In the past i have made a method to sort strings alphabetically in an array as school HW, so umm here it is:
private void sortStringsAlphabetically(){
for (int all = 0; all < names.length; all++) {
for (int i = all + 1; i < names.length; i++) {
if (names[all].compareTo(names[i]) > 0) {
String tmp = names[i];
names[i] = names[all];
names[all] = tmp;
}
}
}
}
This piece of code works for Arrays and specifically for an array of names. You can tweak it to work with the list, it is very simple especially if we consider the wide range of methods in the List interface and all it's implementations.
Cheers.
If you don't wanna to have a huge code who gets every first letter of the word and sort them, do it with Collection.sort()
I don't know what is the proplem on Collection.sort() so use it
Here is a short code, that does exactually this what you want to:
String test = "hello my name is albert";
test = test.replaceAll(" ", "\n");
String[] te = test.split("\n");
List<String> stlist = new ArrayList<String>();
for(String st : te) {
stlist.add(st);
}
Collections.sort(stlist);
Regarding NPE you said it is probably because you are having an null string in head at first and keep adding this in insert method.
this._head = new WordNode();
Also the adding last element is also not proper. Just reuse the insert method like below
insertNode(text.substring(lastIndex,text.length()));
These are the ones I thought having problem when you are converting string to lined list
You can use the below code to handle the first null
private void insertNode(String word) {
if (this._head == null) {
this._head = new WordNode(word, null);
} else {
WordNode newWord = new WordNode(_head._word, _head.getNext());
_head._word = word;
_head.setNext(newWord);
}
}
I am referencing my code to mathbits website on SelectionSorting, changing the variables accordingly from the examples int to String for my case, and adding in sort by alphabetical order as well.
Below is my current code for SelectionSort of students by lastName:
public static void SelectionSort(Student[] st) {
int i, j, first;
String temp;
String jLastName = "";
String firstLastName = "";
String iLastName ="";
for (i = st.length - 1; i > 0; i--) {
first = 0;
for (j = 1; j <= i; j++)
{
if (st[j].getLastName() != null) {
jLastName=st[j].getLastName();
if (st[first].getLastName() != null) {
firstLastName = st[first].getLastName();
if ((jLastName.compareToIgnoreCase(firstLastName)) < 0) {
first = j;
}
}
}
}
iLastName = st[i].getLastName();
temp = firstLastName;
firstLastName = iLastName;
iLastName = temp;
}
}
Pardon me for the naming of the variables.
The code does not give me error. However, the output does not show that it has been sorted according to alpabetical order. May I know which part have I made a mistake in? Thank you
This algorithm is for sorting in descending order.
temp = st[ first ];
st[ first ] = st[ i ];
st[ i ] = temp;
Here is my code
public class NEW {
String Firstname;
String Lastname;
String Position;
int Jnum;
String Team;
public static void main(String[] args) throws Exception {
String a = JOptionPane.showInputDialog("Enter in 0 to sort by First Name\nEnter in 1 to sort by Last Name\n" +
"Enter in 2 to sort by position\nEnter in 4 to sort by Team names");
int q = Integer.parseInt(a);
File input = new File("Roster.txt");
Scanner players = new Scanner(input);
NEW [] array = new NEW [435];
int x=0;
while (players.hasNext()){
array[x] = new NEW();
array[x].Firstname = players.next();
array[x].Lastname = players.next();
array[x].Position = players.next();
array[x].Jnum = players.nextInt();
array[x].Team = players.next();
}
JOptionPane.showMessageDialog(null, array.toString()," ", JOptionPane.INFORMATION_MESSAGE);
players.close();
}
public static NEW[] BubbleSort(int num, NEW []array){
int p=0;
if (num==0){
String temp = null;
for(int k =1;k<435;k++){
for(int i=0;i<435-k;i++){
if(array[i].Firstname.compareTo(array[i+1].Firstname)>0){
temp = array[i].Firstname;
array[i].Firstname=array[i+1].Firstname;
array[i+1].Firstname= temp;
}
p++;
}
}
return array;
}
if (num==1){
String temp = null;
for(int k =1;k<435;k++){
for(int i=0;i<435-k;i++){
if(array[i].Lastname.compareTo(array[i+1].Lastname)>0){
temp = array[i].Lastname;
array[i].Lastname=array[i+1].Lastname;
array[i+1].Lastname= temp;
}
p++;
}
}
return array;
}
if (num ==2){
String temp = null;
for(int k =1;k<435;k++){
for(int i=0;i<435-k;i++){
if(array[i].Position.compareTo(array[i+1].Position)>0){
temp = array[i].Position;
array[i].Position=array[i+1].Position;
array[i+1].Position= temp;
}
p++;
}
}
return array;
}
if (num ==3){
int temp = 0;
for(int k =1;k<435;k++){
for(int i=0;i<435-k;i++){
if(array[i].Jnum>(array[i+1].Jnum))
temp = array[i].Jnum;
array[i].Jnum=array[i+1].Jnum;
array[i+1].Jnum= temp;
p++;
}
}
return array;
}
if (num ==4){
String temp = null;
for(int k =1;k<435;k++){
for(int i=0;i<435-k;i++){
if(array[i].Team.compareTo(array[i+1].Team)>0){
temp = array[i].Team;
array[i].Team=array[i+1].Team;
array[i+1].Team= temp;
}
p++;
}
}
return array;
}
else return array;
}
}
In the stack trace, there will be the name of your source file and a line number. These will tell you exactly which line of code is the source of the problem, which is ultimately that you are trying to access an element of a collection where there is none. For example:
List<String> l = Collections.emptyList();
String s = l.get(0); //will throw NoSuchElementException
Or it might also indicate that you are iterating over the end of an Iterator (note that a Scanner implements Iterator<String>):
Iterator<String> itr = Collections.singleton("Hey").iterator();
itr.next(); // ok!
itr.next(); //will throw NoSuchElementException
Every time you call next() on an Iterator, the "pointer" moves forwards. If you need to access the next element more than once, you need to save it in a local variable, and always use hasNext() to check that an element is available:
while (itr.hasNext()) {
String s = itr.next();
System.out.println("Length of \"" + s + "\" is: " + s.length()); //access twice
}
Unless you are using itr.remove(), you can take advantage of the java foreach loop, which removes the need for writing much of the boilerplate above, although this will not work in the case of a Scanner (which is an Iterator - foreach only works on instances of Iterable):
for (String s : someIterable) {
//can use s as many times as you want
}
As oxbow_lakes mentions, more information about the exception would be good.
But this code is suspicious:
while (players.hasNext()){
array[x] = new NEW();
array[x].Firstname = players.next();
array[x].Lastname = players.next();
array[x].Position = players.next();
array[x].Jnum = players.nextInt();
array[x].Team = players.next();
}
If players has fewer than five tokens available at the top of the loop, one of those nexts is going to fail. All that hasNext tells you is that there is at least one token available. You're assuming here that at least one means you have all five, which is (apparently) not a valid assumption as you're getting the exact exception that next is documented to throw when there's no token available.
you have used hasNext() method which actually is an enumerator() change ur array into a list... it would be much easier.. also you used next()
change it to List newelement = new LinkedList();
then the other codes..
sir, its not that he has more than 435 in the file.. its that its less than 435..
and thats why it returned null...
he used next()
make it into a list...
atleast it would be equal to what you have inputed.. it would not be 435 but it would be equal to the length of the file...
as stated by this link
http://download.oracle.com/javase/1.4.2/docs/api/java/util/NoSuchElementException.html