Типы ссылок по умолчанию равны null, чтобы указать, что они не ссылаются на какой-либо объект. Следовательно, если вы попытаетесь получить доступ к объекту, на который ссылаетесь, а его нет, вы получите исключение NullReferenceException.
Для Ex:
SqlConnection connection = null;
connection.Open();
Когда вы запускаете это кода, вы получите:
System.NullReferenceException: Object reference not set to an instance of an object.
Вы можете избежать этой ошибки, например, следующим образом:
if (connection != null){
connection.Open();
}
Примечание. Чтобы избежать этой ошибки, вы всегда должны инициализировать свои объекты прежде чем пытаться что-либо сделать с ними.
В дополнение к подходу грубой силы существует три способа решения этой проблемы. Я запишу их все. Коды java прошли тесты на онлайн-сайте судьи под названием leetcode: http://www.leetcode.com/onlinejudge#question_84 . поэтому я уверен, что коды верны.
Решение 1: динамическое программирование + n * n матрица как кеш
время: O (n ^ 2), пробел: O (n ^ 2 )
Основная идея: используйте n * n-матрицу dp [i] [j] для кеширования минимальной высоты между баром [i] и баром [j]. Начните заполнять матрицу из прямоугольников шириной 1.
public int solution1(int[] height) {
int n = height.length;
if(n == 0) return 0;
int[][] dp = new int[n][n];
int max = Integer.MIN_VALUE;
for(int width = 1; width <= n; width++){
for(int l = 0; l+width-1 < n; l++){
int r = l + width - 1;
if(width == 1){
dp[l][l] = height[l];
max = Math.max(max, dp[l][l]);
} else {
dp[l][r] = Math.min(dp[l][r-1], height[r]);
max = Math.max(max, dp[l][r] * width);
}
}
}
return max;
}
Решение 2: динамическое программирование + 2 массива в качестве кеша.
время: O (n ^ 2), пробел: O (n)
Основная идея: это решение похоже на решение 1, но экономит некоторое пространство. Идея состоит в том, что в решении 1 мы строим матрицу из строки 1 в строку n. Но в каждой итерации только предыдущая строка способствует построению текущей строки. Таким образом, мы используем два массива в качестве предыдущей строки и текущей строки по очереди.
public int Solution2(int[] height) {
int n = height.length;
if(n == 0) return 0;
int max = Integer.MIN_VALUE;
// dp[0] and dp[1] take turns to be the "previous" line.
int[][] dp = new int[2][n];
for(int width = 1; width <= n; width++){
for(int l = 0; l+width-1 < n; l++){
if(width == 1){
dp[width%2][l] = height[l];
} else {
dp[width%2][l] = Math.min(dp[1-width%2][l], height[l+width-1]);
}
max = Math.max(max, dp[width%2][l] * width);
}
}
return max;
}
Решение 3: используйте стек.
time: O (n), space: O (n)
Это решение сложно, и я узнал, как это сделать из описания без графиков и с графиками . Я предлагаю вам прочитать две ссылки, прежде чем читать мои объяснения ниже. Трудно объяснить без графиков, поэтому мои объяснения могут быть трудными.
Ниже приводятся мои объяснения:
public int solution3(int[] height) {
int n = height.length;
if(n == 0) return 0;
Stack<Integer> left = new Stack<Integer>();
Stack<Integer> right = new Stack<Integer>();
int[] width = new int[n];// widths of intervals.
Arrays.fill(width, 1);// all intervals should at least be 1 unit wide.
for(int i = 0; i < n; i++){
// count # of consecutive higher bars on the left of the (i+1)th bar
while(!left.isEmpty() && height[i] <= height[left.peek()]){
// while there are bars stored in the stack, we check the bar on the top of the stack.
left.pop();
}
if(left.isEmpty()){
// all elements on the left are larger than height[i].
width[i] += i;
} else {
// bar[left.peek()] is the closest shorter bar.
width[i] += i - left.peek() - 1;
}
left.push(i);
}
for (int i = n-1; i >=0; i--) {
while(!right.isEmpty() && height[i] <= height[right.peek()]){
right.pop();
}
if(right.isEmpty()){
// all elements to the right are larger than height[i]
width[i] += n - 1 - i;
} else {
width[i] += right.peek() - i - 1;
}
right.push(i);
}
int max = Integer.MIN_VALUE;
for(int i = 0; i < n; i++){
// find the maximum value of all rectangle areas.
max = Math.max(max, width[i] * height[i]);
}
return max;
}