数组、链表、跳表

数组、链表、跳表

难理解的代码不推荐多练习,主题还是通俗易懂、高效、易实现编码
基础的题目,其实训练的是某种固定思路,或者套路
编程的思路方法:多从自顶向下的编程思想出发
在这里插入图片描述
在这里插入图片描述

移动零:move-zeroes

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

自己开始的思路:
1.先把所有的0放到最后
2.再把原数组所有的0删除
 for i in range(len(nums))
    if nums[i] ==0 :
       nums.append(0)
 for i in range(len(nums))
       if nums[i] ==0 :
       nums.delete(0)

国内站:
java版

/*
思路:

*/
class Solution {
    public void moveZeroes(int[] nums) {

        int j = 0;
        for (int i=0;i<nums.length;i++) {
            if(nums[i] != 0) {
                nums[j] = nums[i];
                if(i != j  ) {
                    nums[i] = 0;  // 这里相当于完成了一次前后交换
                }
                j++;
            }
        }

    }
}

/*
评价:

优点: 时间复杂度低
缺点: 程序理解难度较高

*/


/*
思路:
1. 第一次遍历的时候,j指针记录非0的个数,只要是非0的统统都赋给nums[j]
2. 第二次遍历把末尾的元素都赋为0即可
*/
class Solution {
	public void moveZeroes(int[] nums) {
		if(nums==null) {
			return;
		}
		//第一次遍历的时候,j指针记录非0的个数,只要是非0的统统都赋给nums[j]
		int j = 0;
		for(int i=0;i<nums.length;++i) {
			if(nums[i]!=0) {
				nums[j++] = nums[i];
			}
		}
		//非0元素统计完了,剩下的都是0了
		//所以第二次遍历把末尾的元素都赋为0即可
		for(int i=j;i<nums.length;++i) {
			nums[i] = 0;
		}
	}
}	

/*
评价:

优点: 时间复杂度低、程序理解难度较低
缺点: 待写 

*/

这个代码可以默写5遍
在这里插入图片描述
python版:

补充:

->常常出现在python函数定义的函数名后面,为函数添加元数据,描述函数的返回类型,从而方便开发人员使用。比如:

通常的写法是:

def attrs(self) -> _Attrs: pass 这种写法通常是写在函数的函数名后面

def add(x, y) -> int: return x+y 这里面,元数据表明了函数的返回值为int类型。 ,
->_Attr则表明函数返回的是一个外部可访问的类的私有变量。


# 先数零的个数,再用append 和 remove暴力操作
class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        n = nums.count(0)
        for i in range(n): # n是0的个数
            nums.append(0)  # 时间复杂度 O(1)
            nums.remove(0)  # 时间复杂度 O(n)
'''
评价:
  优点:程序简洁易懂
  缺点:时间复杂度高




'''

class Solution(object):
    def moveZeroes(self, nums):
        zero_position = 0  # records the position of "0"
        for i in xrange(len(nums)):
            if nums[i] != 0:
                nums[i], nums[zero_position] = nums[zero_position], nums[i]
                zero_position += 1
'''
解说:
zero_position在遇到0就会比i少1,所以他一直记录着最早的0的位置,只要遇到非0就进行互换,所以只要扫描一遍就可以解决


评价:
  优点:程序
  缺点:时间复杂度一般




'''

c++版:

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int i,j;
        for(i=0,j=0;i<nums.size();i++){
            if(nums[i]!=0){
                swap(nums[i],nums[j]);
                j++;
            }
        }
    }
}; 

国际站:

java版

// Shift non-zero values as far forward as possible
// Fill remaining space with zeros
/*
思路:

*/
public void moveZeroes(int[] nums) {
    if (nums == null || nums.length == 0) return;        

    int insertPos = 0;
    for (int num: nums) {
        if (num != 0) nums[insertPos++] = num;
    }        

    while (insertPos < nums.length) {
        nums[insertPos++] = 0;
    }
}

python版:

c++版:

装最多水:container-with-most-water

在这里插入图片描述

国内站
java版:


/*
思路:

*/

class Solution {
    public int maxArea(int[] a) {
        // 1.枚举 :left bar x ,right bar y, (x-y)*height_diff
        //    时间复杂度:O(n^2)
        
        int max = 0;
        for (int i = 0; i < a.length-1; ++i) {
            for (int j = i+1; j< a.length; j++) {
                int area =(j - i) * Math.min(a[i],a[j]);
                max = Math.max(max,area);
            }
        }
        return max;

    }
}

/*
评价:
优点:写出来容易
缺点:时间复杂度过高

*/
/*
思路:

*/
// 时间复杂度为 O(n),左右边界i j ,中间收敛;

class Solution {
    public int maxArea(int[] a) {
 
      int max=0;
      for(int i=0,j=a.length-1;i<j;) {
         int minHeight = a[i] <a[j] ?a[i++]:a[j--];
         int area = (j-i+1)*minHeight;
         max = Math.max(max,area);
      }

      return max;
 
    }
}

/*
评价:
优点:时间复杂度低
缺点:

*/

class Solution {
    public int maxArea(int[] height) {
        int i = 0, j = height.length - 1, res = 0;
        while(i < j){
            res = height[i] < height[j] ? 
                Math.max(res, (j - i) * height[i++]): 
                Math.max(res, (j - i) * height[j--]); 
        }
        return res;
    }
}

在这里插入图片描述
python版:

class Solution:
    def maxArea(self, height: List[int]) -> int:
        i, j, res = 0, len(height) - 1, 0
        while i < j:
            if height[i] < height[j]:
                res = max(res, height[i] * (j - i))
                i += 1
            else:
                res = max(res, height[j] * (j - i))
                j -= 1
        return res

在这里插入图片描述

c++版:

class Solution {
public:
    int maxArea(vector<int>& height) {

    int res = 0;
    int i = 0;
    int j = height.size() - 1;
    while (i < j) {
        int area = (j - i) * min(height[i], height[j]);
        res = max(res, area);
        if (height[i] < height[j]) {
            i++;
        } else {
            j--;
        }
    }
    return res;

    }
};

在这里插入图片描述

国外站
java版:

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

爬楼梯:climbing-stairs
典型的套路题,第一次做感觉贼难,没有思路,会了以后就感觉, 套路,全都是套路,很简单

注意:优化的思想主要有两种,一是空间换时间, 二是升维

其实为什么说算法基本就那么几个,贪心、动态、分支等,而且他们的差别也不是很大,其一根本原因就是
计算机基本只适合处理机械重复性问题,用的语言就是if else for while recursion的逻辑或重复性代码
这对于教学就有指导意义,就是也需要重复练习。

做题的时候懵比的时候,怎么办?
第一步是,从0开始找规律
第二步是,找出规律中的重复子问题
第三步是,编码

国内站

/*
思路:
找最近重复子问题
一般只写:if else for while recursion的重复性代码


*/




/*
评价:
优点:
缺点:
*/

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

f(1):1
f(2):2
f(3):f(1)+f(2)=3
f(4): f(2)+f(3)=5

跨到第n阶的时候,只有两种可能,一是从n-1跨过来,二就是从n-2阶跨过来

所以 :


f(n)=f(n-1)+f(n-2)

for(int i =0;i<=n;++i) {
    a[i]=a[i-1]+a[i-2]         
}

'''

class Solution(object):
    def climbStairs(self,n) :
        if(n<=2):return n
        f1,f2,f3=1,2,3
        for i in range(3,n+1):
            f3=f1+f2
            f1=f2
            f2=f3
        return f3


'''
评价:
  优点:
  缺点:
'''

在这里插入图片描述



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

The problem seems to be a dynamic programming one. Hint: the tag also suggests that!
Here are the steps to get the solution incrementally.

Base cases:
if n <= 0, then the number of ways should be zero.
if n == 1, then there is only way to climb the stair.
if n == 2, then there are two ways to climb the stairs. One solution is one step by another; the other one is two steps at one time.

The key intuition to solve the problem is that given a number of stairs n, if we know the number ways to get to the points [n-1] and [n-2] respectively, denoted as n1 and n2 , then the total ways to get to the point [n] is n1 + n2. Because from the [n-1] point, we can take one single step to reach [n]. And from the [n-2] point, we could take two steps to get there.

The solutions calculated by the above approach are complete and non-redundant. The two solution sets (n1 and n2) cover all the possible cases on how the final step is taken. And there would be NO overlapping among the final solutions constructed from these two solution sets, because they differ in the final step.

Now given the above intuition, one can construct an array where each node stores the solution for each number n. Or if we look at it closer, it is clear that this is basically a fibonacci number, with the starting numbers as 1 and 2, instead of 1 and 1.

/*
思路:

*/

class Solution {
    public int climbStairs(int n) {
        if(n <= 0) return 0;
        if(n == 1) return 1;
        if(n == 2) return 2;

        int one_step_before = 2;
        int two_steps_before = 1;
        int all_ways = 0;

        for(int i=2; i<n; i++){
            all_ways = one_step_before + two_steps_before;
            two_steps_before = one_step_before;
            one_step_before = all_ways;
        }
        return all_ways;

    }
}

/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

3数之和:3sum

2数之和:

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int[] a= new int[2];
        int numsSize=nums.length;
        for(int i=0;i<numsSize-1;i++) {
            for(int j=i+1;j<numsSize;j++) {
                if(nums[i]+nums[j] == target) {
                    a[0] =i;
                    a[1] =j;
                    return a;

                }

            }
  
        }        
        return new int[0];
    }
}

国内站

/*
思路:
找最近重复子问题
一般只写:if else for while recursion的重复性代码


*/


class Solution {
    // 1.暴力求解  时间复杂度为 O(n^3)
    // 2.hash表求解 时间复杂度 O(n)
    // 3.左右下标 先排序
    public List<List<Integer>> threeSum(int[] num) {
      Arrays.sort(num);
      List<List<Integer>> res =new LinkedList<>();
      for(int i =0;i<num.length-2;i++) {
        if(i ==0 || (i>0 && num[i]!=num[i-1])) {
          int lo=i+1,hi=num.length-1,sum=0-num[i];
          while(lo<hi) {
            if(num[lo]+num[hi]==sum) {
              res.add(Arrays.asList(num[i],num[lo],num[hi]));
              while(lo <hi && num[lo]==num[lo+1]) lo++;
              while(lo< hi && num[hi] == num[hi-1]) hi--;
              lo++;hi--;

            }else if(num[lo]+num[hi]<sum) lo++;
            else hi--;
          }
        }
      }
      return res;
 
    }
}

/*
评价:
优点:
缺点:
*/

在这里插入图片描述

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''




'''
评价:
  优点:
  缺点:
'''



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

The idea is to sort an input array and then run through all indices of a possible first element of a triplet. For each possible first element we make a standard bi-directional 2Sum sweep of the remaining part of the array. Also we want to skip equal elements to avoid duplicates in the answer without making a set or smth like that.

/*
思路:

*/

public List<List<Integer>> threeSum(int[] num) {
    Arrays.sort(num);
    List<List<Integer>> res = new LinkedList<>(); 
    for (int i = 0; i < num.length-2; i++) {
        if (i == 0 || (i > 0 && num[i] != num[i-1])) {
            int lo = i+1, hi = num.length-1, sum = 0 - num[i];
            while (lo < hi) {
                if (num[lo] + num[hi] == sum) {
                    res.add(Arrays.asList(num[i], num[lo], num[hi]));
                    while (lo < hi && num[lo] == num[lo+1]) lo++;
                    while (lo < hi && num[hi] == num[hi-1]) hi--;
                    lo++; hi--;
                } else if (num[lo] + num[hi] < sum) lo++;
                else hi--;
           }
        }
    }
    return res;
}


/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

在这里插入图片描述

反转链表:reverse-linked-list/

class Solution {
        public ListNode reverseList(ListNode head) {
            /* iterative solution */
            ListNode newHead = null;
            while (head != null) {
                ListNode next = head.next;
                head.next = newHead;
                newHead = head;
                head = next;
            }
            return newHead;
        }
}

public ListNode reverseList(ListNode head) {
    /* iterative solution */
    ListNode newHead = null;
    while (head != null) {
        ListNode next = head.next;
        head.next = newHead;
        newHead = head;
        head = next;
    }
    return newHead;
}

public ListNode reverseList(ListNode head) {
    /* recursive solution */
    return reverseListInt(head, null);
}

private ListNode reverseListInt(ListNode head, ListNode newHead) {
    if (head == null)
        return newHead;
    ListNode next = head.next;
    head.next = newHead;
    return reverseListInt(next, head);
}

两两交换链表中的节点:swap-nodes-in-pairs/

public class Solution {
    public ListNode swapPairs(ListNode head) {
        if ((head == null)||(head.next == null))
            return head;
        ListNode n = head.next;
        head.next = swapPairs(head.next.next);
        n.next = head;
        return n;
    }
}

环形链表:linked-list-cycle/

国内站

/*
思路:
找最近重复子问题
一般只写:if else for while recursion的重复性代码


*/




/*
评价:
优点:
缺点:
*/

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''




'''
评价:
  优点:
  缺点:
'''



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

1.Use two pointers, walker and runner.
2.walker moves step by step. runner moves two steps at time.
3.if the Linked List has a cycle walker and runner will meet at somepoint.

/*
思路:

*/

public class Solution {
    public boolean hasCycle(ListNode head) {
        if(head==null) return false;
        ListNode walker = head;
        ListNode runner = head;
        while(runner.next!=null && runner.next.next!=null) {
            walker = walker.next;
            runner = runner.next.next;
            if(walker==runner) return true;
        }
        return false;
    }
}


/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

环形链表 II:linked-list-cycle-ii/

国内站

/*
思路:
找最近重复子问题
一般只写:if else for while recursion的重复性代码


*/




/*
评价:
优点:
缺点:
*/

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''




'''
评价:
  优点:
  缺点:
'''



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

Define two pointers slow and fast. Both start at head node, fast is twice as fast as slow. If it reaches the end it means there is no cycle, otherwise eventually it will eventually catch up to slow pointer somewhere in the cycle.

Let the distance from the first node to the the node where cycle begins be A, and let say the slow pointer travels travels A+B. The fast pointer must travel 2A+2B to catch up. The cycle size is N. Full cycle is also how much more fast pointer has traveled than slow pointer at meeting point.

A+B+N = 2A+2B
N=A+B

From our calculation slow pointer traveled exactly full cycle when it meets fast pointer, and since originally it travled A before starting on a cycle, it must travel A to reach the point where cycle begins! We can start another slow pointer at head node, and move both pointers until they meet at the beginning of a cycle.

/*
思路:

*/


public class Solution {
            public ListNode detectCycle(ListNode head) {
                ListNode slow = head;
                ListNode fast = head;
        
                while (fast!=null && fast.next!=null){
                    fast = fast.next.next;
                    slow = slow.next;
                    
                    if (fast == slow){
                        ListNode slow2 = head; 
                        while (slow2 != slow){
                            slow = slow.next;
                            slow2 = slow2.next;
                        }
                        return slow;
                    }
                }
                return null;
            }
        }

/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

K 个一组翻转链表:reverse-nodes-in-k-group/

class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        ListNode curr = head;
        int count = 0;
        while (curr != null && count != k) { // find the k+1 node
            curr = curr.next;
            count++;
        }
        if (count == k) { // if k+1 node is found
            curr = reverseKGroup(curr, k); // reverse list with k+1 node as head
            // head - head-pointer to direct part, 
            // curr - head-pointer to reversed part;
            while (count-- > 0) { // reverse current k-group: 
                ListNode tmp = head.next; // tmp - next head in direct part
                head.next = curr; // preappending "direct" head to the reversed list 
                curr = head; // move head of reversed part to a new node
                head = tmp; // move "direct" head to the next node in direct part
            }
            head = curr;
        }
        return head;
    }
}

在这里插入图片描述

删除排序数组中的重复项:remove-duplicates-from-sorted-array/

国内站

/*
思路:
找最近重复子问题
一般只写:if else for while recursion的重复性代码


*/

class Solution {
    public int removeDuplicates(int[] A) {
        if ( A.length == 0 ) return 0;
        int j =0;
        for (int i =0;i<A.length;i++) {
              if (A[i]!=A[j]){
                  A[++j]=A[i];
              }
        }
        return ++j;
    }
}


/*
评价:
优点:
缺点:
*/

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''




'''
评价:
  优点:
  缺点:
'''



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

/*
思路:

*/

public int removeDuplicates(int[] A) {
    if (A.length==0) return 0;
    int j=0;
    for (int i=0; i<A.length; i++)
        if (A[i]!=A[j]) A[++j]=A[i];
    return ++j;
}


/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

旋转数组:rotate-array/
国内站

/*
思路:
找最近重复子问题
一般只写:if else for while recursion的重复性代码


*/




/*
评价:
优点:
缺点:
*/

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''




'''
评价:
  优点:
  缺点:
'''



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

/*
思路:

*/

class Solution {

    public void rotate(int[] nums, int k) {
        k %= nums.length;
        reverse(nums, 0, nums.length - 1);
        reverse(nums, 0, k - 1);
        reverse(nums, k, nums.length - 1);
    }

    public void reverse(int[] nums, int start, int end) {
        while (start < end) {
            int temp = nums[start];
            nums[start] = nums[end];
            nums[end] = temp;
            start++;
            end--;
        }
    }
}


/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

合并两个有序链表:merge-two-sorted-lists/
国内站

/*
思路:
找最近重复子问题
一般只写:if else for while recursion的重复性代码


*/




/*
评价:
优点:
缺点:
*/

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''




'''
评价:
  优点:
  缺点:
'''



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

/*
思路:

*/

class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2){
            if(l1 == null) return l2;
            if(l2 == null) return l1;
            if(l1.val < l2.val){
                l1.next = mergeTwoLists(l1.next, l2);
                return l1;
            } else{
                l2.next = mergeTwoLists(l1, l2.next);
                return l2;
            }
    }
}


/*
评价:
优点:
缺点:
*/

在这里插入图片描述

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

合并两个有序数组:merge-sorted-array/
国内站

/*
思路:
找最近重复子问题
一般只写:if else for while recursion的重复性代码
*/

class Solution {
    public void merge(int A[],int m,int B[], int n) {
        int i = m-1;
        int j = n-1;
        int k = m+n-1;
        while(i>-1 && j >-1) {
            A[k--] =  A[i] > B[j] ? A[i--] : B[j--];
        }
        while(j > -1) {
               A[k--] = B[j--];
        }

    }
}






/*
评价:
优点:
缺点:
*/

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''




'''
评价:
  优点:
  缺点:
'''



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

/*
思路:

*/

public void merge(int A[], int m, int B[], int n) {
    int i=m-1, j=n-1, k=m+n-1;
    while (i>-1 && j>-1) A[k--]= (A[i]>B[j]) ? A[i--] : B[j--];
    while (j>-1)         A[k--]=B[j--];
}


/*
评价:
优点:
缺点:
*/

在这里插入图片描述

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

两数之和:two-sum/

国内站

/*
思路:
找最近重复子问题
一般只写:if else for while recursion的重复性代码


*/




/*
评价:
优点:
缺点:
*/

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''




'''
评价:
  优点:
  缺点:
'''



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

/*
思路:

*/

class Solution {

        public int[] twoSum(int[] numbers, int target) {
        int[] result = new int[2];
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        for (int i = 0; i < numbers.length; i++) {
            if (map.containsKey(target - numbers[i])) {
                result[1] = i;
                result[0] = map.get(target - numbers[i]);
                return result;
            }
            map.put(numbers[i], i);
        }
        return result;
    }
}


/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

加一:plus-one/

国内站

/*
思路:
找最近重复子问题
一般只写:if else for while recursion的重复性代码


*/




/*
评价:
优点:
缺点:
*/

/*
思路:

*/




/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''




'''
评价:
  优点:
  缺点:
'''



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

国外站

/*
思路:

*/

class Solution {
    public int[] plusOne(int[] digits) {
            
        int n = digits.length;
        for(int i=n-1; i>=0; i--) {
            if(digits[i] < 9) {
                digits[i]++;
                return digits;
            }
            
            digits[i] = 0;
        }
        
        int[] newNumber = new int [n+1];
        newNumber[0] = 1;
        
        return newNumber;
    }
}


/*
评价:
优点:
缺点:
*/

python版:



'''
思路:

'''

'''
评价:
  优点:
  缺点:
'''

c++版:

/*
思路:

*/


/*
评价:
优点:
缺点:
*/

二 实战题目解析:移动零

在这里插入图片描述

三 实战题目解析:盛水最多的容器、爬楼梯

四 实战题目解析:3数之和、环形链表

一 数组、链表、跳表的基本实现和特性

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

链表的时间复杂度

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

跳表主要是运用在Redis中,在一般工程中用的比较少。
跳表主要是运用在Redis中的原因
在这里插入图片描述
改进的主要思想:
升维的思想:以空间换时间

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
https://www.jianshu.com/p/b1ab4a170c3c

https://leetcode-cn.com/problems/lru-cache/solution/

https://redisbook.readthedocs.io/en/latest/internal-datastruct/skiplist.html

https://www.zhihu.com/question/20202931

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值