@@ -242,9 +242,9 @@ func main() {
242242
2432431、 数据状况层面是否可以优化
244244
245- 2、 问题本身是否可以优化。单调性,首位指针 (头指针往右走,尾指针往左走)等
245+ 2、 问题本身是否可以优化。单调性,首尾指针 (头指针往右走,尾指针往左走)等
246246
247- > 遇到一个问题我们先观察,问题本身和范围是否可以建立单调性,至于需要用哪个原型来解决,串口和首位指针法是常见的流程 。所以窗口和首位指针主要用来解决单调性的
247+ > 遇到一个问题我们先观察,问题本身和范围是否可以建立单调性,至于需要用哪个原型来解决,窗口和首位指针法是常见的流程 。所以窗口和首位指针主要用来解决单调性的
248248
249249## 1.2 单调栈
250250
@@ -278,182 +278,141 @@ func main() {
278278> 如果存在相等元素的情况,我们栈中每个元素保存为list表示相等元素列表。无法直接进入单调栈时,弹出list最右侧的元素,该元素右侧最近的比自己小的数,就是迫使它弹出的那个数。该元素左侧最近比它小的数,就是自身的这个list压着的的list的最右的数。list的相同元素有两种情况,一种是两个数相等且挨着,另外一种是某个位置释放了中间位置的数后遇到相等元素,进入一个list中去。画栈模拟可看出
279279
280280
281- ``` Java
282-
283- package class01 ;
281+ ``` Go
282+ package main
284283
285- import java.util.List ;
286- import java.util.ArrayList ;
287- import java.util.Stack ;
284+ import " fmt"
288285
289- public class Code03_MonotonousStack {
286+ // 单调栈
290287
291- // 数组中没有重复值的情况
292- public static int [][] getNearLessNoRepeat (int [] arr ) {
293- int [][] res = new int [arr. length][2 ];
294- Stack<Integer > stack = new Stack<> ();
295- for (int i = 0 ; i < arr. length; i++ ) {
296- while (! stack. isEmpty() && arr[stack. peek()] > arr[i]) {
297- int popIndex = stack. pop();
298- int leftLessIndex = stack. isEmpty() ? - 1 : stack. peek();
299- res[popIndex][0 ] = leftLessIndex;
300- res[popIndex][1 ] = i;
301- }
302- stack. push(i);
303- }
304- while (! stack. isEmpty()) {
305- int popIndex = stack. pop();
306- int leftLessIndex = stack. isEmpty() ? - 1 : stack. peek();
307- res[popIndex][0 ] = leftLessIndex;
308- res[popIndex][1 ] = - 1 ;
309- }
310- return res;
288+ // 数组中没有重复值的情况
289+ func getNearLessNoRepeat (arr []int ) [][]int {
290+ res := make ([][]int , len (arr))
291+ for i := 0 ; i < len (arr); i++ {
292+ res[i] = make ([]int , 2 )
311293 }
312294
313- // arr [3, 2, 1, 4, 5]
314- // 0 1 2 3 4
315-
316- // 表示 0这个数左边最近比0小的没有,位置是-1,右边1。1位置数左边最近比0小的没有-1,右边2
317- // [
318- // 0 : [-1, 1 ]
319- // 1 : [-1, 2 ]
320-
321- // ]
322- // 数组中存在重复值的情况
323- public static int [][] getNearLess (int [] arr ) {
324- int [][] res = new int [arr. length][2 ];
325-
326-
327- // List<Integer> -> 放的是位置,同样值的东西,位置压在一起
328- // 代表值 底 -> 顶 小 -> 大
329- Stack<List<Integer > > stack = new Stack<> ();
330- for (int i = 0 ; i < arr. length; i++ ) { // i -> arr[i] 进栈
331- // 栈底 -> 栈顶, 小 -> 大
332- while (! stack. isEmpty() && arr[stack. peek(). get(0 )] > arr[i]) {
333- List<Integer > popIs = stack. pop();
334- // 取位于下面位置的列表中,最晚加入的那个
335- int leftLessIndex = stack. isEmpty() ? - 1 : stack. peek(). get(stack. peek(). size() - 1 );
336- for (Integer popi : popIs) {
337- res[popi][0 ] = leftLessIndex;
338- res[popi][1 ] = i;
339- }
340- }
341- // 相等的、比你小的
342- if (! stack. isEmpty() && arr[stack. peek(). get(0 )] == arr[i]) {
343- stack. peek(). add(Integer . valueOf(i));
295+ // 模拟一个栈
296+ stack := make ([]int , 0 )
297+ for i := 0 ; i < len (arr); i++ {
298+ for len (stack) != 0 && arr[stack[len (stack) - 1 ]] > arr[i] {
299+ // 出栈 stack pop
300+ popIndex := stack[len (stack) - 1 ]
301+ stack = stack[:len (stack) - 1 ]
302+
303+ leftLessIndex := 0
304+ if len (stack) == 0 {
305+ leftLessIndex = -1
344306 } else {
345- ArrayList<Integer > list = new ArrayList<> ();
346- list. add(i);
347- stack. push(list);
348- }
349- }
350- while (! stack. isEmpty()) {
351- List<Integer > popIs = stack. pop();
352- // 取位于下面位置的列表中,最晚加入的那个
353- int leftLessIndex = stack. isEmpty() ? - 1 : stack. peek(). get(stack. peek(). size() - 1 );
354- for (Integer popi : popIs) {
355- res[popi][0 ] = leftLessIndex;
356- res[popi][1 ] = - 1 ;
307+ leftLessIndex = stack[len (stack) - 1 ]
357308 }
309+
310+ res[popIndex][0 ] = leftLessIndex
311+ res[popIndex][1 ] = i
358312 }
359- return res;
313+ // stack push i
314+ stack = append (stack, i)
360315 }
361316
362- // for test
363- public static int [] getRandomArrayNoRepeat ( int size ) {
364- int [] arr = new int [( int ) ( Math . random() * size) + 1 ];
365- for ( int i = 0 ; i < arr . length; i ++ ) {
366- arr[i] = i;
367- }
368- for ( int i = 0 ; i < arr . length; i ++ ) {
369- int swapIndex = ( int ) ( Math . random() * arr . length);
370- int tmp = arr[swapIndex];
371- arr[swapIndex] = arr[i];
372- arr[i] = tmp;
317+ for len (stack) != 0 {
318+ // 出栈 stack pop
319+ popIndex := stack[ len (stack) - 1 ]
320+ stack = stack[: len (stack) - 1 ]
321+
322+ leftLessIndex := 0
323+ if len (stack) == 0 {
324+ leftLessIndex = - 1
325+ } else {
326+ // leftLessIndex = stack peek
327+ leftLessIndex = stack[ len (stack) - 1 ]
373328 }
374- return arr;
329+
330+ res[popIndex][0 ] = leftLessIndex
331+ res[popIndex][1 ] = -1
375332 }
376333
377- // for test
378- public static int [] getRandomArray (int size , int max ) {
379- int [] arr = new int [(int ) (Math . random() * size) + 1 ];
380- for (int i = 0 ; i < arr. length; i++ ) {
381- arr[i] = (int ) (Math . random() * max) - (int ) (Math . random() * max);
382- }
383- return arr;
334+ return res
335+ }
336+
337+ // arr [3, 2, 1, 4, 5]
338+ // 0 1 2 3 4
339+
340+ // 表示 0这个数左边最近比0小的没有,位置是-1,右边1。1位置数左边最近比0小的没有-1,右边2
341+ // [
342+ // 0 : [-1, 1 ]
343+ // 1 : [-1, 2 ]
344+
345+ // ]
346+ // 数组中存在重复值的情况
347+ func getNearLess (arr []int ) [][]int {
348+ res := make ([][]int , len (arr))
349+ for i := 0 ; i < len (arr); i++ {
350+ res[i] = make ([]int , 2 )
384351 }
385352
386- // for test
387- public static int [][] rightWay (int [] arr ) {
388- int [][] res = new int [arr. length][2 ];
389- for (int i = 0 ; i < arr. length; i++ ) {
390- int leftLessIndex = - 1 ;
391- int rightLessIndex = - 1 ;
392- int cur = i - 1 ;
393- while (cur >= 0 ) {
394- if (arr[cur] < arr[i]) {
395- leftLessIndex = cur;
396- break ;
397- }
398- cur-- ;
399- }
400- cur = i + 1 ;
401- while (cur < arr. length) {
402- if (arr[cur] < arr[i]) {
403- rightLessIndex = cur;
404- break ;
405- }
406- cur++ ;
353+ // []int -> 放的是位置,同样值的东西,位置压在一起
354+ // 代表值 底 -> 顶 小 -> 大
355+ stack := make ([][]int , 0 )
356+
357+ for i := 0 ; i < len (arr); i++ { // i -> arr[i] 进栈
358+ // 栈底 -> 栈顶, 小 -> 大
359+ for len (stack) != 0 && arr[stack[len (stack) - 1 ][0 ]] > arr[i] {
360+ // 出栈 stack pop
361+ popIs := stack[len (stack) - 1 ]
362+ stack = stack[:len (stack) - 1 ]
363+
364+ // 取位于下面位置的列表中,最晚加入的那个
365+ leftLessIndex := 0
366+ if len (stack) == 0 {
367+ leftLessIndex = -1
368+ } else {
369+ leftLessIndex = stack[len (stack) - 1 ][len (stack[len (stack) - 1 ]) - 1 ]
407370 }
408- res[i][0 ] = leftLessIndex;
409- res[i][1 ] = rightLessIndex;
410- }
411- return res;
412- }
413371
414- // for test
415- public static boolean isEqual (int [][] res1 , int [][] res2 ) {
416- if (res1. length != res2. length) {
417- return false ;
418- }
419- for (int i = 0 ; i < res1. length; i++ ) {
420- if (res1[i][0 ] != res2[i][0 ] || res1[i][1 ] != res2[i][1 ]) {
421- return false ;
372+ for _,popi := range popIs {
373+ res[popi][0 ] = leftLessIndex
374+ res[popi][1 ] = i
422375 }
423376 }
424377
425- return true ;
378+ // 相等的、比你小的
379+ if len (stack) != 0 && arr[stack[len (stack) - 1 ][0 ]] == arr[i] {
380+ stack[len (stack) - 1 ] = append (stack[len (stack) - 1 ], i)
381+ } else {
382+ list := make ([]int , 0 )
383+ list = append (list, i)
384+ // stack push
385+ stack = append (stack, list)
386+ }
426387 }
427388
428- // for test
429- public static void printArray (int [] arr ) {
430- for (int i = 0 ; i < arr. length; i++ ) {
431- System . out. print(arr[i] + " " );
389+ for len (stack) != 0 {
390+ // stack pop
391+ popIs := stack[len (stack) - 1 ]
392+ stack = stack[:len (stack) - 1 ]
393+
394+ // 取位于下面位置的列表中,最晚加入的那个
395+ leftLessIndex := 0
396+ if len (stack) == 0 {
397+ leftLessIndex = -1
398+ } else {
399+ leftLessIndex = stack[len (stack) - 1 ][len (stack[len (stack) - 1 ]) - 1 ]
432400 }
433- System . out. println();
434- }
435401
436- public static void main (String [] args ) {
437- int size = 10 ;
438- int max = 20 ;
439- int testTimes = 2000000 ;
440- for (int i = 0 ; i < testTimes; i++ ) {
441- int [] arr1 = getRandomArrayNoRepeat(size);
442- int [] arr2 = getRandomArray(size, max);
443- if (! isEqual(getNearLessNoRepeat(arr1), rightWay(arr1))) {
444- System . out. println(" Oops!" );
445- printArray(arr1);
446- break ;
447- }
448- if (! isEqual(getNearLess(arr2), rightWay(arr2))) {
449- System . out. println(" Oops!" );
450- printArray(arr2);
451- break ;
452- }
402+ for _,popi := range popIs {
403+ res[popi][0 ] = leftLessIndex
404+ res[popi][1 ] = -1
453405 }
454406 }
407+ return res
455408}
456409
410+ func main () {
411+ arr := []int {4 , 3 , 5 , 6 , 7 }
412+ fmt.Println (getNearLessNoRepeat (arr))
413+ arr = []int {4 , 3 , 5 , 4 , 3 , 3 , 6 , 7 }
414+ fmt.Println (getNearLess (arr))
415+ }
457416```
458417
459418### 1.2.2 单调栈的应用
0 commit comments