I tried to solve
https://leetcode.com/problems/maximum-subarray/submissions/
using Java
I usually try these things using Eclipse before submit on online.
Here I attached codes in Eclipse
public class PrintAnnotationExample{
public static void main(String[] args) {
int index = 0;
int max =0;
int temp = 0;
int[] test = new int[] {-2,1,-3,4,-1,2,1,-5,4};
while(index<test.length) {
temp+= test[index];
if(temp <0) {
while(index<test.length-1 && test[index]<0) {
++index;
}
temp = 0;
}
max = (max >= temp ) ? max : temp;
++index;
}
///
System.out.println(max);
}
}
It worked! the expected output is 6, and it makes 6 either.
However,
In Leetcode submission page, It doesn't work
class Solution {
public int index = 0;
public int max =0;
public int temp = 0;
public int maxSubArray(int[] nums) {
while(index<nums.length) {//아직 배열범위 안에 있을경우
temp+= nums[index];
if(temp <0) {
while(index<nums.length-1 && nums[index]<0) {
++index;
}
temp = 0;
}
max = (max >= temp ) ? max : temp;
++index;
}
return max;
}
}
It shows me 1, not 6...
weird, may be I got something wrong in my head about Java semantics..
The codes you are executing in Eclipse and Leetcode are clearly different, so you need to focus on the differences between them ... rather than concluding (incorrectly) that there are compiler / language differences.
One of the differences is that in the Eclipse version index, max and temp are local variables. In the Leetcode version they are instance variables that don't get initialized each time your method is called. If LeetCode instantiates your class once and calls the method multiple times, this will lead to incorrect behavior.
may be I got something wrong in my head about Java semantics.
Maybe. Or it could just be a mistake.
But either way, it is inadvisable to use instance variables to hold the state of a method call. Use local variables for instead:
Using local variables for this avoids the mistake you made; i.e. forgetting to reinitialize.
Using instance variables for this makes the method non-reentrant; i.e. concurrent or overlapping calls to the method will interfere with each other. This will be problematic if the method is called recursively, or if it is called from multiple threads.
Related
I've written code for a foobar challenge that works in my IDE but not in the solutions file provided by foobar. Also, is there anyway to show the output even if the test fails? Possibly to with it being a static method or the input being {1, 2, 3, 4} whereas mine is working with new int {1,2,3,4,5}? My code is:
public static int solution(int[] l) {
List<Integer> numberList = Arrays.stream(l).boxed().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
while (true) {
StringBuilder number = new StringBuilder();
int i = 0;
while (i < numberList.size()) {
number.append(numberList.get(i));
i++;
}
List<Integer> startingList = Arrays.stream(l).boxed().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
int testValue = numberList.size();
for (Integer integer : numberList) {
if (startingList.contains(integer)) {
startingList.remove(integer);
testValue--;
}
}
if (testValue == 0) {
int f = 0;
int total = 0;
while (f < numberList.size()) {
total = total + numberList.get(f);
f++;
}
if (total % 3 == 0) {
StringBuilder answer = new StringBuilder();
int c = 0;
while (c < numberList.size()) {
answer.append(numberList.get(c));
c++;
}
return Integer.parseInt(answer.toString());
}
}
Integer nextNumber = Integer.parseInt(number.toString()) - 1;
String[] stringArray = valueOf(nextNumber).split("");
numberList = new ArrayList<>();
for (String s : stringArray) {
numberList.add(Integer.parseInt(s));
}
}
}
Pretty rubbish but it does the job (at least in my IDE!)
As mentioned in a comment on the question, you should undoubtedly give some more context for your questions (since it is pretty unclear what your code is intended to do). I'm pretty sure I've inferred the actual question from context though, and I can suggest a couple of problems. In short (and a pretty good assumption for coding in general) the issue is not the environment running your code incorrectly, but rather your code having missed bugs due to lack of comprehensive testing. If you had presented a number of sample inputs and results I would guess you would have seen that your solution does not work locally.
The Java List.remove() method takes an index rather than a value to be removed (https://docs.oracle.com/javase/8/docs/api/java/util/List.html). The way it is used in your sample will result in throwing exceptions in a number of circumstances. Proper testing would have identified this (and will pick up most of your problems if fixed)
What happens if there is no solution? For example, an input of {1, 1} is going to get into a pretty messy state as the 'nextNumber' value slips below 0. You should know what the desired behavior is in this situation, and your tests should cover it before you try to upload a solution
This happened to me as well, but I then realized that my compilation was not successful because I have not imported the package that I am using at the top of the source code file like all java programs are write
In groovy I can iterate through numbers using that simple syntax:
(1..10).each {
do_domething it
}
What is the shortest syntax to do that in Java? I am now exploring streams and I came up with such an idea:
IntStream.range(0, 10)
.forEach(do_domething());
It is even longer than the traditional way (below), but seems to be more concise.
for (int i = 0; i < 10; i++)
do_domething()
I am just curious if there is shorter and readable way of doing it. I don't know everything about Java so I am just asking, probably there is no such thing, but I would like to make sure.
If you need to use IntStream.range repeatedly in one class, you can reduce verbosity by using a static import:
import static java.util.stream.IntStream.range;
Then the syntax becomes
range(0, 10).forEach(...)
Beyond that, there's not much else I can suggest. In my view it is a bit ridiculous that we have to write for(int i = 0; i < n; i++) repeatedly, but at least it has the advantage of being instantly recognisable.
There are some major differences between those two that do not make them drop in replacements of each other.
A return from a regular for-loop will return from your method, but for the stream/lambda version it returns from the lambda function. See below.
for (int i = 0; i < 10; i++) {
if (i == 5) {
return;//returns from the whole method
}
}
IntStream.range(0, 10).forEach((i -> {
if (i == 5) {
return; //returns only from the lambda
}
}));
Another major difference is how the two code blocks interact with variables. For lambdas to interact with variables that our outside its scope, they need to be final. So the stream/lambda code below won't compile.
String x = "";
for (int i = 0; i < 10; i++) {
if (i == 5) {
x = "5";
}
}
IntStream.range(0, 10).forEach((i -> {
if (i == 5) {
x = "5"; //wont compile
}
}));
There might be other differences between the two. But for me that last one has caused problems that has lead me to continue using the regular for-loop.
If you want concise you can use a helper method.
public static void each(int start, int end, IntConsumer consumer) {
IntStream.range(start, end).forEach(consumer);
}
and then you can write
import static java.lang.System.out;
each(0, 10, out::println);
If "each" is a bit verbose you could use a connector character like
public static void ⁀(int start, int end, IntConsumer consumer) {
IntStream.range(start, end).forEach(consumer);
}
public static void main(String... args) {
⁀(0, 10, out::println);
}
prints
0
1
2
3
4
5
6
7
8
9
You could create a helper function to create an array
public static int[] range(final int length){
return IntStream.range(0, length).toArray();
}
Then using a foreach loop all you need to write is:
for(int i : range(10)) {
do_domething();
}
You can use the so-called "Facetious Arrow" operator (it looks like an arrow "-->") to write the loop slightly more briefly. [Pro Tip: It's not really an arrow]
for (int i=10;i-->0;)doSomething();
For example:
for (int i=10;i-->0;)System.out.println(i);
Prints:
9
8
7
6
5
4
3
2
1
0
I am looking for some help with the below problem. This is not my original code and I am quite new to Java, so I may be missing something obvious.
The code spawns some effects in a game I have, however there does not seem to be any upper limit on how many effects are spawned. Is there any way I can restrict the upper value of effects to some integer value? Say 20? Or can I make this value a random integer from say 20 to 30?
I have been trying to restrict the upper size of the list size but it doesn't seem to work.
Any suggestions appreciated.
I have also tried adjusting the value for(int j = 0; j < i; j++) to something like for(int j = 0; j < 20; j++), but this seems to have no effect either and the effects spawn as before.
I have also tried removing int i = list.size(); and Actor actor = (Actor)list.get(j); so that the code just relies on the for loop, but the code will not compile: it seems to require the code Actor actor = (Actor)list.get(j);. I get a cannot resolve symbol error for the following:
symbol : class pos
location: package actor
if(!flag && actor.pos.getAbsPoint().distance(point3d) < 10000D && (actor instanceof TypeBomber) && actor.getArmy() != myArmy)
symbol : variable actor
location: class com.maddox.il2.objects.vehicles.stationary.CandC$FireUnit
if(!flag && actor.pos.getAbsPoint().distance(point3d) < 10000D && (actor instanceof TypeBomber) && actor.getArmy() != myArmy)
symbol : variable actor
location: class com.maddox.il2.objects.vehicles.stationary.CandC$FireUnit
if(!flag && actor.pos.getAbsPoint().distance(point3d) < 10000D && (actor instanceof TypeBomber) && actor.getArmy() != myArmy)
public boolean danger()
{
boolean flag = false;
Point3d point3d = new Point3d();
pos.getAbs(point3d);
List list = Engine.targets();
World.MaxVisualDistance = 50000F;
int i = list.size();
for(int j = 0; j < i; j++)
{
Actor actor = (Actor)list.get(j);
if(!flag && actor.pos.getAbsPoint().distance(point3d) < 10000D && (actor instanceof TypeBomber) && actor.getArmy() != myArmy)
{
Random random = new Random();
int k = random.nextInt(500);
int l = k - 250;
k = random.nextInt(500);
int i1 = k - 250;
Eff3DActor.New(this, null, new Loc(l, i1, 0.0D, 0.0F, 90F, 0.0F), 1.0F, "Effects/Smokes/CityFire.eff", 600F);
flag = true;
int j1 = random.nextInt(10);
wait = (float)(1.0D + (double)j1 * 0.10000000000000001D);
}
}
Thanks for any help. Like I said, I'm sorry if I am missing something obvious.
I cannot say for sure what all of that code is doing, however, it appears that your function actually returns flag past the point that you pasted? It also appears that the size of the list of Actors is the upper bound of how many smoke effects can be made (limited by how many pass the if statement). That said I would try something like this (in order to preserve the rest of the function)
if(!flag && actor.pos.getAbsPoint().distance(point3d) < 10000D && (actor instanceof TypeBomber) && actor.getArmy() != myArmy)
{
if (renderedCount < 20)
{
Random random = new Random();
int k = random.nextInt(500);
int l = k - 250;
k = random.nextInt(500);
int i1 = k - 250;
Eff3DActor.New(this, null, new Loc(l, i1, 0.0D, 0.0F, 90F, 0.0F), 1.0F, "Effects/Smokes/CityFire.eff", 600F);
int j1 = random.nextInt(10);
wait = (float)(1.0D + (double)j1 * 0.10000000000000001D);
renderedCount += 1;
}
flag = true;
}
Make sure you declare int renderedCount before the for loop.
Now this should limit the function to creating 20 smoke effects each time it is called. Which brings us to the problems you are having where this kind of approach does not appear to work. Since you mentioned this is a game, I would be willing to bet that this function is called many times a minute (more than likely once per 'game tick'). If that is the case, limiting the number of smoke effects created by the function will not appear to do much of anything in the game. In order to limit the number completely you would have to do something a little more complex where you keep track of the number of smoke effects currently going globally. Which would probably involve keeping track of how much time has passed since the effect was started... (which it appears that wait might be the time the effect continues after it is started).
As for suggestions about how to keep track of things globally I might recommend a singleton and some methods on the singleton canCreate() and didCreate(float timeValue) then replace renderedCount < 20 with canCreate() and replace renderedCount += 1 with didCreate(wait).
Anyway, I hope this helps you some.
p.s. the complexity that goes with limiting this is a prime example of why ModelViewController is so important when designing something like this...
EDIT: rough singleton
public class SmokeCountSingleton {
private static SmokeCountSingleton instance = null;
private List<Long> smokeList = new ArrayList<Long>();
protected SmokeCountSingleton() {
}
public static SmokeCountSingleton getInstance() {
if(instance == null) {
instance = new SmokeCountSingleton();
}
return instance;
}
public boolean canCreate() {
cleanList()
return (smokeList.size() <= 20)
}
public void didCreate(float duration) {
//duration appears to be in seconds but we want it in milliseconds
smokeList.add(System.currentTimeMillis() + duration*1000)
}
private void cleanList(){
//remove items from list who have exceeded their duration
// have a value less than System.currentTimeMillis()
}
}
I do not have time to finish fleshing it out but hopefully that is enough to get you going.
The point of a singleton is that there is only ever one instance of it, it's kind of like having a database or some other external server that your program can use but without as much overhead. This way you don't ever have to declare it either, so you don't have to worry about where you would need to declare it, but it still acts as if you have a global list. To access the singleton instance (and the methods) you would just do:
SmokeCountSingleton.getInstance().canCreate()
SmokeCountSingleton.getInstance().didCreate(someDurationValue)
Like I said earlier, my Java is a little rusty, and I just mocked this up in the edit window; so apologies if it doesn't work 'out of the box'.
Also, as a side note, you may very well have multiple threads running that call functions where this would get accessed. So you may want to check out synchronized key word in Java...
use list.size() directly, instead of passing it to i. It will return number of objects the list is holding.
You can also use an Iterator or ListIterator to iterate through the list elements, as it will be easier, If you use these.
Example:-
Actor actor; //It would be better if you create variable here and use the same variable for different objects.
Iterator iter = list.iterator();
while(iter.hasNext()){
actor = (Actor)iter.next();
....//Rest of the code
}
I'll answer the question regarding whether we can set a maximum for a list. Hope that will help you to get to know Java better :)
Generally, an implementation of List does not have a maximum size, you can always add more element at the end of it.
In order to work around this would be to use a primitive array of Actor:
private static final int MAX_NUMBER_OF_ACTORS = 20
Actor[] actors = new Actor[MAX_NUMBER_OF_ACTORS];
That said, I would encourage you to use what the List interface has to offer to you, via its various implementations. Use, for example, an Arraylist and ovverride its add method:
public class ActorList extends ArrayList<Actor> {
private static final int MAX_NUMBER_OF_ACTORS = 20
#Override
public boolean add(Store s) {
boolean result = false;
if (this.size() <= MAX_NUMBER_OF_ACTORS){
result = super.add(s);
}else{
// Notify number maximum of actors have been reached (logging, whatever processing you want here...)
}
return result;
}
}
That would give you a nive control over the maximum size of your list of Actor instances.
Can anybody explain the following codes to me? It is from the Android source code.
The first line looks to me is to initialize an integer array, but what about those codes enclosed in braces? I mean are those codes syntax correct since the braces part
seems to be tangling?
// high priority first
mPriorityList = new int[mNetworksDefined];
{
int insertionPoint = mNetworksDefined-1;
int currentLowest = 0;
int nextLowest = 0;
while (insertionPoint > -1) {
for (NetworkAttributes na : mNetAttributes) {
if (na == null) continue;
if (na.mPriority < currentLowest) continue;
if (na.mPriority > currentLowest) {
if (na.mPriority < nextLowest || nextLowest == 0) {
nextLowest = na.mPriority;
}
continue;
}
mPriorityList[insertionPoint--] = na.mType;
}
currentLowest = nextLowest;
nextLowest = 0;
}
}
Yeah those code blocks are absolutely fine. They are viable syntax. Rather they are useful.
What happens there is, the code is just shifted to an unnamed-block, to provide them a block scope. So, any variables defined inside that block won't be visible outside.
int[] a = new int[10];
{
int x = 10;
a[0] = x;
System.out.println(x);
}
System.out.println(x); // Error. x not visible here.
So, those braces just creates a local block scope, that's it. Nothing more special in them. Though, you won't feel the magic of those blocks in the above code.
This way of coding is generally used to minimize the scope of your local variables, which is absolutely a good idea, specially when, the variables created inside that block won't be used anywhere else.
So, if used without those braces, those variables will just hang around, waiting for the garbage collector to free them up, at the same time, enjoying the trip towards the end of current scope, that might be a very long method.
I am a newbie Computer Science high school student and I have trouble with a small snippet of code. Basically, my code should perform a basic CLI search in an array of integers. However, what happens is I get what appears to be an infinite loop (BlueJ, the compiler I'm using, gets stuck and I have to reset the machine). I have set break points but I still don't quite get the problem...(I don't even understand most of the things that it tells me)
Here's the offending code (assume that "ArrayUtil" works, because it does):
import java.util.Scanner;
public class intSearch
{
public static void main(String[] args)
{
search();
}
public static void search()
{
int[] randomArray = ArrayUtil.randomIntArray(20, 100);
Scanner searchInput = new Scanner(System.in);
int searchInt = searchInput.nextInt();
if (findNumber(randomArray, searchInt) == -1)
{
System.out.println("Error");
}else System.out.println("Searched Number: " + findNumber(randomArray, searchInt));
}
private static int findNumber(int[] searchedArray, int searchTerm)
{
for (int i = 0; searchedArray[i] == searchTerm && i < searchedArray.length; i++)
{
return i;
}
return -1;
}
}
This has been bugging me for some time now...please help me identify the problem!
I don't know about the infinite loop but the following code is not going to work as you intended. The i++ can never be reached so i will always have the value 0.
for (int i = 0; searchedArray[i] == searchTerm && i < searchedArray.length; i++)
{
return i;
}
return -1;
You probably mean this:
for (int i = 0; i < searchedArray.length; i++)
{
if (searchedArray[i] == searchTerm)
{
return i;
}
}
return -1;
I don't know what is the class ArrayUtil (I can not import is using my Netbeans). When I try to change that line with the line int[] randomArray = {1 , 2, 3, 5, 7, 10, 1 , 5}; It works perfectly.
And you should change the loop condition. I will not tell you why but try with my array and you will see the bug soon. After you see it, you can fix it:)
There are 4 basic issues here.
1. Putting searchedArray[i] == searchTerm before i < searchedArray.length can result in an out-of-bounds exception. You must always prevent that kind of code.
2. Your intention seems to be the opposite of your code. Your method name implies finding a search term. But, your code implies that you want to continue your loop scan until the search term is not found, although your loop won't do that either. Think of "for (; this ;) { that } " as "while this do that".
3. Place a break point at the beginning of "search". Then, with a small array, step through the code line by line with the debugger and watch the variables. They don't lie. They will tell you exactly what's happening.
4. Please use a standard IDE and compiler, such as Eclipse and Sun's JDK 6 or 7. Eclipse with JDK 7 is a serious combination that doesn't exhibit a strange "infinite loop" as you describe above.