Skip to content

Latest commit

 

History

History
323 lines (262 loc) · 9.47 KB

leetcode算法.md

File metadata and controls

323 lines (262 loc) · 9.47 KB

leetcode算法

1.反转字符串

描述: 编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

你可以假设数组中的所有字符都是 ASCII码表中的可打印字符。

示例 1:

输入:["h","e","l","l","o"]
输出:["o","l","l","e","h"]
2.删除链表的节点

描述:给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。

返回删除后的链表的头节点。

输入: head = [4,5,1,9], val = 5
输出: [4,1,9]
3.数组中重复的数字

描述:在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

输入:[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3 
4.合并两个排序的链表

描述:输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。

输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
5.字符交换最少次数

描述: 把一个0-1(只包含0和1的串)进行排序,0在一边,1在另一边,你可以交换任意两个位置,问最少交换多少次?

输入 : str = "00101110101100101" 输出:5

那如果每次只能相邻两个数交换,最少多少次呢

6.字符串指定长度整体交换

描述:给定一个字符串str和长度leftSize,请把字符串leftSize左边的整体部分与右边交换 ,要求额外空间复杂度O(1)

输入:str = "abdesfc" leftSize = 3   输出:"esfcabd"

如果对时间复杂度有要求呢??

7.重建二叉树

描述:输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

 前序遍历 preorder = [3,9,20,15,7]
 中序遍历 inorder = [9,3,15,20,7]

返回如下的二叉树:

    3
   / \
  9  20
    /  \
   15   7

提示:中序数组分成左右两部分后递归遍历

private static  TreeNode buildTreeUtil(int[] preOrder, int preStart, int preEnd,int [] inorder,int inStart,int inEnd){}
8.调整数组顺序使奇数位于偶数前面

描述:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。

输入:nums = [1,2,3,4]
输出:[1,3,2,4] 
注:[3,1,2,4] 也是正确的答案之一。
9.最长不含重复字符的子字符串

描述:请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。

 输入: "abcabcbb"
 输出: 3
10.顺时针打印矩阵

描述:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。

 *  输入:matrix = [
 *                  [1, 2, 3],
 *                  [4, 5, 6],
 *                  [7, 8, 9]
 *                  ]
 *  输出:[1,2,3,6,9,8,7,4,5]

思路 定义top、bottom、left、right四个子针

11.二叉树遍历
 *       39
 *     /   \
 *   24     64
 *  / \     /
 * 23  30  53
 *           \
 *           60
 * 先序遍历:根左右 : 39 24 23 30 64 53 60
 * 中序遍历:左根右 : 23 24 30 39 53 60 64
 * 后序遍历:左右根 : 23 30 24 60 53 64 39
12.两个链表的第一个公共节点

描述:输入两个链表,找出它们的第一个公共节点(节点相同,并非节点的内容相同)。

 输入:intersectVal = 8, 
 listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], 
 skipA = 2, skipB = 3
 输出:Reference of the node with value = 8

输入解释:相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。在 A 中,相交节点前有 2 个节点;在B中,相交节点前有 3 个节点。

13.二叉树按层次遍历
 * eg:
 *       39
 *     /   \
 *   24     64
 *  / \     /
 * 23  30  53
 *           \
 *           60
 
 输出:39, 24, 64, 23, 30, 53, 60

提示可以用队列解决

14.连续子数组的最大和
  • 输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。
  • 要求时间复杂度为O(n)。
 输入: nums = [-2,1,-3,4,-1,2,1,-5,4]
 输出: 6
 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。

思路:带上你比我大我就要,比我小丢弃

15.快排

思想:

  • 先从数列中取出一个数作为基准数。
  • 分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
  • 再对左右区间重复第二步,直到各区间只有一个数
eg: 
输入:arr = [5,4,7,1,2,8,9] 
输出:[1,2,4,5,7,8,9]
16.归并排序

思想:

  • 将两个或两个以上的有序序列合并成一个新的有序序列
  • 合并的方法是比较各子序列的第一个记录的键值,最小的一个就是排序的第一个记录的键值。
  • 取出这个记录,继续比较各子序列现有的第一个记录的键值,便可以找出排序后的第二个键值。
  • 然后开始递归,最终得到排序结果。
eg:
输入:arr = [5,4,7,1,2,8,9] 
输出:[1,2,4,5,7,8,9]

需要借助一个临时数组

17.翻转二叉树

翻转一棵二叉树。

输入:

     4
   /   \
  2     7
 / \   / \
1   3 6   9

输出:

     4
   /   \
  7     2
 / \   / \
9   6 3   1
18.旋转矩阵

描述: 给你一幅由 N × N 矩阵表示的图像,其中每个像素的大小为 4 字节。请你设计一种算法,将图像旋转 90 度。

  • 不占用额外内存空间能否做到?
给定 matrix = 
[
  [1,2,3],
  [4,5,6],
  [7,8,9]
],

原地旋转输入矩阵,使其变为:
[
  [7,4,1],
  [8,5,2],
  [9,6,3]
]
19.数组中数字出现的次数 II

描述:在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。

 输入:nums = [9,1,7,9,7,9,7]
 输出:1
20.和为s的两个数字

描述:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。

 输入:nums = [2,7,11,15], target = 9
 输出:[2,7] 或者 [7,2]

双指针解法

21.指定范围查询

描述:数组为{3,2,2,3,1},查询为(0,3,2),意思是在数组里下标0-3这个范围上,有几个2? 返回2。

假设给你一个数组arr,对这个数组的查询非常频繁,请返回所有查询结果

输入:arr={3,2,2,3,1}, 
      startId = 0, endId = 3, queryId = 2    
输出:2

思路: 借助hashMap,问题转换为顺序数组指定范围查找

22.直方图的水量

描述:给定一个直方图(也称柱状图),假设有人从上面源源不断地倒水,最后直方图能存多少水量?直方图的宽度为 1。 image

上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的直方图,在这种情况下,可以接 6 个单位的水(蓝色部分表示水)

输入: [0,1,0,2,1,0,1,3,2,1,2,1]
输出: 6

思路:从第二格到N-2格,依次计算每格的可以装水的容量,最后相加。Math.(leftMax,rightMax) - arr[i]

第二种,考虑动态规划

23.二维数据消除0

描述:给你一个二维数组matrix,所有数据都是整数,请你把其中所有的0做上下左右方向的延迟,放回处理之后的matrix 比如:注意其中有两个0,那么每个0都向上下左右延伸

要求:整个处理过程都直接在matrix上发生,除此之外额外空间复杂度请做到O(1),也就是只用有限介个变量

输入: 
arr = {
        {7 ,0 ,1 ,4 ,6},
        {6 ,5 ,3 ,2 ,1},
        {4 ,2 ,1 ,0 ,3},
        {8 ,2 ,1 ,2 ,9},
        {0 ,3 ,6 ,4 ,8}
        };

输出:
    0 0 0 0 0
    0 0 3 0 1
    0 0 0 0 0
    0 0 1 0 9
    0 0 0 0 0

思路:把为0的坐标标记在第一行和第一列标记0,还得标记第一行和第一列是否有原生的0(两个变量标记) ,然后处理从第二行第二列开始, 最后处理第一行和第一列

24.二维数组统计1的个数
  • 描述:给定一个只由0和1组成的二维数组matrix,每一行都可以保证所有的0在左侧,1在右侧,将那些行拥有最多的1,请放入一个列表返回
  输入:
     0 0 0 0 1 1
     0 0 0 0 0 1
     0 0 1 1 1 1
     1 1 1 1 1 1
     0 0 0 0 0 0
     1 1 1 1 1 1
     
  输出:[3,5]

思路:每一行从右向左扫描,记录最大值,放入一个临时空间,最终的结果应该是右上到左下的一个过程

如果每一行的数据很大可以用二分查找1进行优化

25. 查找大于N/K次数的数

描述:给定一个长度为N的数组,和一个大于1的正整数K,如果有那些数次数大于等于N/K,就放回这些数

  • 要求:时间复杂度O(N),额外空间复杂度O(k)
 输入:arr = [4,1,7,5,5,5,8,2,7]  k = 3
 输出:[5]

这题重点是额外空间复杂度O(k)