1. longest-consecutive-sequence

Given an unsorted array of integers, find the length of the longest consecutive elements sequence.

For example,
Given[100, 4, 200, 1, 3, 2],
The longest consecutive elements sequence is[1, 2, 3, 4]. Return its length:4.

Your algorithm should run in O(n) complexity.

给定一个整形数组,求出最长的连续序列。例如数组[100,4,200,1,3,2],最长的连续序列长度为[1,2,3,4],长度为4。要求时间复杂度为O(n)。

排序的话至少要O(nlgn) 的复杂度。O(n)的复杂度,目前只找到了使用hash来解决的方案,add, remove, contains 等方法的复杂度都是 O(1),因此两次遍历的操作复杂度为 O(n)。

public static int longestConsecutive(int[] num) {
// if array is empty, return 0
if (num.length == 0) {
return 0;
} Set<Integer> set = new HashSet<Integer>();
int max = 1; for (int e : num)
set.add(e); for (int e : num) {
int left = e - 1;
int right = e + 1;
int count = 1; while (set.contains(left)) {
count++;
set.remove(left);
left--;
} while (set.contains(right)) {
count++;
set.remove(right);
right++;
} max = Math.max(count, max);
} return max;
}

2. surrounded-regions

Given a 2D board containing'X'and'O', capture all regions surrounded by'X'.

A region is captured by flipping all'O's into'X's in that surrounded region .

For example,

X X X X
X O O X
X X O X
X O X X

After running your function, the board should be:

X X X X
X X X X
X X X X
X O X X

典型的BFS题目。遍历每个字符,如果是“O”,则从当前字符开始BFS遍历,如果周围也是“O”则加入当前遍历的队列,知道遍历完所有相邻的“O”,于此同时,判断每个O是否是被包围的,只有由一个O是没有被包围的,则当前遍历的O的集合都是没有被包围的,因为这些O都是相连的。

当然,此题使用DFS也可以,只是测试数据过大,提交时StackOverFlow.

1)BFS 广度优先搜索

public class Solution {
// use a queue to do BFS
private Queue<Integer> queue = new LinkedList<Integer>(); public void solve(char[][] board) {
if (board == null || board.length == 0)
return; int m = board.length;
int n = board[0].length; // merge O's on left & right boarder
for (int i = 0; i < m; i++) {
if (board[i][0] == 'O') {
bfs(board, i, 0);
} if (board[i][n - 1] == 'O') {
bfs(board, i, n - 1);
}
} // merge O's on top & bottom boarder
for (int j = 0; j < n; j++) {
if (board[0][j] == 'O') {
bfs(board, 0, j);
} if (board[m - 1][j] == 'O') {
bfs(board, m - 1, j);
}
} // process the board
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (board[i][j] == 'O') {
board[i][j] = 'X';
} else if (board[i][j] == '#') {
board[i][j] = 'O';
}
}
}
} private void bfs(char[][] board, int i, int j) {
int n = board[0].length; // fill current first and then its neighbors
fillCell(board, i, j); while (!queue.isEmpty()) {
int cur = queue.poll();
int x = cur / n;
int y = cur % n; fillCell(board, x - 1, y);
fillCell(board, x + 1, y);
fillCell(board, x, y - 1);
fillCell(board, x, y + 1);
}
} private void fillCell(char[][] board, int i, int j) {
int m = board.length;
int n = board[0].length;
if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] != 'O')
return; // add current cell is queue & then process its neighbors in bfs
queue.offer(i * n + j);
board[i][j] = '#'; // 用#标识要保留的O
}
}

2)DFS深度优先搜索

public void solve(char[][] board) {
if(board == null || board.length==0)
return; int m = board.length;
int n = board[0].length; //merge O's on left & right boarder
for(int i=0;i<m;i++){
if(board[i][0] == 'O'){
merge(board, i, 0);
} if(board[i][n-1] == 'O'){
merge(board, i,n-1);
}
} //merge O's on top & bottom boarder
for(int j=0; j<n; j++){
if(board[0][j] == 'O'){
merge(board, 0,j);
} if(board[m-1][j] == 'O'){
merge(board, m-1,j);
}
} //process the board
for(int i=0;i<m;i++){
for(int j=0; j<n; j++){
if(board[i][j] == 'O'){
board[i][j] = 'X';
}else if(board[i][j] == '#'){
board[i][j] = 'O';
}
}
}
} public void merge(char[][] board, int i, int j){
if(i<0 || i>=board.length || j<0 || j>=board[0].length)
return; if(board[i][j] != 'O')
return; board[i][j] = '#'; // 递归实现深度优先搜索
merge(board, i-1, j);
merge(board, i+1, j);
merge(board, i, j-1);
merge(board, i, j+1);
}

3. Best Time to Buy and Sell Stock  I II III

3.1 Best Time to Buy and Sell Stock  I

Description: Say you have an array for which the ith element is the price of a given stock on day i. If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find
the maximum profit.

题意:用一个数组表示股票每天的价格,数组的第i个数表示股票在第i天的价格。 如果只允许进行一次交易,也就是说只允许买一支股票并卖掉,求最大的收益。

分析:动态规划法。从前向后遍历数组,记录当前出现过的最低价格,作为买入价格,并计算以当天价格出售的收益,作为可能的最大收益,整个遍历过程中,出现过的最大收益就是所求。

代码:O(n)时间,O(1)空间。

public class Solution {
public int maxProfit(int[] prices) {
if (prices.length < 2) return 0; int maxProfit = 0;
int curMin = prices[0]; for (int i = 1; i < prices.length; i++) {
curMin = Math.min(curMin, prices[i]);
maxProfit = Math.max(maxProfit, prices[i] - curMin);
} return maxProfit;
}
}

3.2 Best Time to Buy and Sell Stock  II

Description: Say you have an array for which the ith element is the price of a given stock on day i. Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times). However, you may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

题目:用一个数组表示股票每天的价格,数组的第i个数表示股票在第i天的价格。  交易次数不限,   但一次只能交易一支股票,也就是说手上最多只能持有一支股票,求最大收益。

分析:贪心法。从前向后遍历数组,只要当天的价格高于前一天的价格,就算入收益。

代码:时间O(n),空间O(1)。

public class Solution {
public int maxProfit(int[] prices) {
if (prices.length < 2) return 0; int maxProfit = 0;
for (int i = 1; i < prices.length; i++) {
int diff = prices[i] - prices[i - 1];
if (diff > 0) {
maxProfit += diff;
}
} return maxProfit;
}
}

3.3 Best Time to Buy and Sell Stock  III

Description: Say you have an array for which the ith element is the price of a given stock on day i. Design an algorithm to find the maximum profit. You may complete at most two transactions. Note: You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

题意:用一个数组表示股票每天的价格,数组的第i个数表示股票在第i天的价格。最多交易两次,手上最多只能持有一支股票,求最大收益。

分析:动态规划法。以第i天为分界线,计算第i天之前进行一次交易的最大收益preProfit[i],和第i天之后进行一次交易的最大收益postProfit[i],最后遍历一遍,max{preProfit[i] + postProfit[i]} (0≤i≤n-1)就是最大收益。第i天之前和第i天之后进行一次的最大收益求法同Best Time to Buy and Sell Stock I。

代码:时间O(n),空间O(n)。

public class Solution {
public int maxProfit(int[] prices) {
if (prices.length < 2) return 0; int n = prices.length;
int[] preProfit = new int[n];
int[] postProfit = new int[n]; int curMin = prices[0];
for (int i = 1; i < n; i++) {
curMin = Math.min(curMin, prices[i]);
preProfit[i] = Math.max(preProfit[i - 1], prices[i] - curMin);
} int curMax = prices[n - 1];
for (int i = n - 2; i >= 0; i--) {
curMax = Math.max(curMax, prices[i]);
postProfit[i] = Math.max(postProfit[i + 1], curMax - prices[i]);
} int maxProfit = 0;
for (int i = 0; i < n; i++) {
maxProfit = Math.max(maxProfit, preProfit[i] + postProfit[i]);
} return maxProfit;
}
}

4. convert-sorted-array-to-binary-search-tree

Given an array where elements are sorted in ascending order, convert it to a height balanced BST.

从给定的有序数组转成一个平衡二叉树(左子树<根结点<右子树)

/**
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/ public class Solution {
private TreeNode buildTree(int[] num, int start, int end) {
if (start > end) {
return null;
} TreeNode node = new TreeNode(num[(start + end) / 2]);
node.left = buildTree(num, start, (start + end) / 2 - 1);
node.right = buildTree(num, (start + end) / 2 + 1, end);
return node;
} public TreeNode sortedArrayToBST(int[] num) {
if (num == null) {
return null;
}
return buildTree(num, 0, num.length - 1);
}
}

5. plus-one

  Given a non-negative number represented as an array of digits, plus one to the number. 
  The digits are stored such that the most significant digit is at the head of the list.

  给定一个用数组表示的一个数,对它进行加一操作。 
  每一个数位都存储在数组的一个位置上。数组下标从大到小表示数位从低位到高位。

  直接求解,设置一个进位标志carry,初值为1,表示加1,从最低位开始tmp = a[x] + carry, 
a[x] = tmp%10,carry = tmp/10,如果carry不为0对下一位再进行操作,直到所有的数位处理完或者carray为0就退出,如果最后还有carray不为0说明整个数组要扩展一个数位。

public class Solution{
public int[] plusOne(int[] digits) {
int len = digits.length; boolean flag = true; // 进位标记 for (int i = len - 1; i >= 0; i--) {
if (flag) {
if (digits[i] == 9) {
digits[i] = 0;
} else {
digits[i] = digits[i] + 1;
flag = false;
} if (i == 0 && digits[i] == 0) {
int[] y = new int[len + 1];
y[0] = 1;
for (int j = 1; j <= len; j++) {
y[j] = digits[j - 1];
}
digits = y;
}
}
} return digits;
}
}

6. search-a-2d-matrix

Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties

  • Integers in each row are sorted from left to right.
  • The first integer of each row is greater than the last integer of the previous row.

For example,

Consider the following matrix:

[
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]

Given target =3, return true.

解法一:

从右上到左下进行搜索。时间复杂度 O(m + n)

解法二:

如果把第0行,第1行,第i行...第i+1行依次连接起来,使得2D数组被还原为1D数组,那么显然这个1D数组就被转化成为了一个排好序的数组。接下来普通的二分搜索就OK了。  时间复杂度lg(m * n) = lg(m) + lg(n)

// 二分法
public class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
if(matrix==null || matrix.length==0 || matrix[0].length==0)
return false; int m = matrix.length;
int n = matrix[0].length; int start = 0;
int end = m*n-1; while(start<=end){
int mid=(start+end)/2;
int midX=mid/n;
int midY=mid%n; if(matrix[midX][midY]==target)
return true; if(matrix[midX][midY]<target){
start=mid+1;
}else{
end=mid-1;
}
} return false;
}
}

7. rotate image

You are given an n x n 2D matrix representing an image.

Rotate the image by 90 degrees (clockwise).

Follow up:
Could you do this in-place?

二维数组a[n][n] 顺时针旋转90度,  规律 :a[i][j]=a[n-1-j][i]

public class Solution {
public void rotate(int[][] matrix) {
if(matrix == null || matrix.length==0)
return ; int m = matrix.length; int[][] result = new int[m][m]; for(int i=0; i<m; i++){
for(int j=0; j<m; j++){
result[j][m-1-i] = matrix[i][j];
}
} for(int i=0; i<m; i++){
for(int j=0; j<m; j++){
matrix[i][j] = result[i][j];
}
}
}
}

8. spiral-matrix

Given a matrix of m x n elements (mrows, n columns), return all elements of the matrix in spiral order.

For example,
Given the following matrix:

[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]

You should return[1,2,3,6,9,8,7,4,5].

特殊情况: 只有一行或一列;  其他情况,从左到右,从上到下,从右到坐,从下到上,完成一轮,矩阵的长宽缩减2

public class Solution {
public ArrayList<Integer> spiralOrder(int[][] matrix) {
ArrayList<Integer> result = new ArrayList<Integer>(); if(matrix == null || matrix.length == 0) return result; int m = matrix.length;
int n = matrix[0].length; int x=0;
int y=0; while(m>0 && n>0){ //if one row/column left, no circle can be formed
if(m==1){
for(int i=0; i<n; i++){
result.add(matrix[x][y++]);
}
break;
}else if(n==1){
for(int i=0; i<m; i++){
result.add(matrix[x++][y]);
}
break;
} //below, process a circle //top - move right
for(int i=0;i<n-1;i++){
result.add(matrix[x][y++]);
} //right - move down
for(int i=0;i<m-1;i++){
result.add(matrix[x++][y]);
} //bottom - move left
for(int i=0;i<n-1;i++){
result.add(matrix[x][y--]);
} //left - move up
for(int i=0;i<m-1;i++){
result.add(matrix[x--][y]);
} x++;
y++;
m=m-2;
n=n-2;
} return result;
}
}

9. merge-intervals

Given a collection of intervals, merge all overlapping intervals.

For example,
Given[1,3],[2,6],[8,10],[15,18],
return[1,6],[8,10],[15,18]

给定一个区间集合,合并有重叠的区间

先对区间排序,按开始点进行排序,再一个个进行合并;如果结果集合为空或者当前interval与结果集合中最后一个interval不重叠,那么就直接将当前interval加入到结果中;如果发生了重叠,那么修改结果集合中的最后一个interval的右端点(改为当前interval的右端点或不修改)

/**
* Definition for an interval.
* public class Interval {
* int start;
* int end;
* Interval() { start = 0; end = 0; }
* Interval(int s, int e) { start = s; end = e; }
* }
*/
public List<Interval> merge(List<Interval> intervals) {
List<Interval> list = new ArrayList<Interval>();
Comparator<Interval> comparator = new Comparator<Interval>() {
@Override
public int compare(Interval o1, Interval o2) {
if (o1.start == o2.start)
return o1.end - o2.end;
return o1.start - o2.start;
}
};
Collections.sort(intervals, comparator);
for (Interval interval : intervals)
if (list.size() == 0 || list.get(list.size() - 1).end < interval.start)
list.add(new Interval(interval.start, interval.end));
else
list.get(list.size() - 1).end = Math.max(interval.end, list.get(list.size() - 1).end);
return list;
}

10. Merge Sorted Array

Given two sorted integer arrays A and B, merge B into A as one sorted array.

Note:
You may assume that A has enough space to hold additional elements from B. The number of elements initialized in A and B are m and n respectively.

考虑从后往前比较,这样就不会产生需要数据后移的问题了;同时考虑B数组还有剩余的情况。时间复杂度O(n+m)

public class Solution {
public void merge(int A[], int m, int B[], int n) { while(m > 0 && n > 0){
if(A[m-1] > B[n-1]){
A[m+n-1] = A[m-1];
m--;
}else{
A[m+n-1] = B[n-1];
n--;
}
} while(n > 0){
A[m+n-1] = B[n-1];
n--;
}
}
}
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 (k >= 0) {
if (j < 0 || (i >= 0 && A[i] > B[j]))
A[k--] = A[i--];
else
A[k--] = B[j--];
}
}

11. 3sum-closest

Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution.

    For example, given array S = {-1 2 1 -4}, and target = 1.

    The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).

先固定一个数,剩下的用2sum方法解决即可,采用两个指针从前后方向,时间复杂度O(n^2)

public int threeSumClosest(int[] nums, int target) {
int min = Integer.MAX_VALUE;
int result = 0; Arrays.sort(nums); for (int i = 0; i < nums.length; i++) {
int j = i + 1;
int k = nums.length - 1;
while (j < k) {
int sum = nums[i] + nums[j] + nums[k];
int diff = Math.abs(sum - target); if(diff == 0) return sum; if (diff < min) {
min = diff;
result = sum;
}
if (sum <= target) {
j++;
} else {
k--;
}
}
} return result;
}

12. remove element

Given an array and a value, remove all instances of that value in place and return the new length.

The order of elements can be changed. It doesn't matter what you leave beyond the new length.

返回所有删除指定元素的数组

1)把原数组A的元素拷贝到新的数组中,A可以当做新的数组

public class Solution {
public int removeElement(int[] A, int elem) {
int newIndex = 0;
for (int oldIndex = 0; oldIndex < A.length; ++oldIndex) {
if (A[oldIndex] != elem) {
A[newIndex++] = A[oldIndex];
}
oldIndex++;
}
return newIndex;
}
}

2)把不需要的元素放在原数组的尾部

public class Solution {
public int removeElement(int[] A, int elem) {
if (A.length ==0) return A.length;
//if (A.lenth == 1 && A[0] == elem) return 0;
//if (A.lenth == 1 && A[0] != elem) return 1;
int i = 0, j = A.length - 1;
//while (i < j) {
while (i <= j) {
if (A[i] == elem) {
int tmp = A[i];
A[i] = A[j];
A[j] = tmp;
--j;
} else {
++i;
}
}
//return j; 因为while (i<=j)才结束,而不是while (i < j)才结束,所以这里返回j+1
return j + 1;
}
}

leetcode: 数组的更多相关文章

  1. Leetcode数组题*3

    目录 Leetcode数组题*3 66.加一 题目描述 思路分析 88.合并两个有序数组 题目描述 思路分析 167.两数之和Ⅱ-输入有序数组 题目描述 思路分析 Leetcode数组题*3 66.加 ...

  2. LeetCode 数组分割

    LeetCode 数组分割 LeetCode 数组怎么分割可以得到左右最大值的差值的最大 https://www.nowcoder.com/study/live/489/1/1 左右最值最大差 htt ...

  3. LeetCode数组中重复的数字

    LeetCode 数组中重复的数字 题目描述 在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次. ...

  4. LeetCode数组解题模板

    一.模板以及题目分类 1.头尾指针向中间逼近 ; ; while (pos1<pos2) { //判断条件 //pos更改条件 if (nums[pos1]<nums[pos2]) pos ...

  5. LeetCode数组查找问题

    简单的二分查找法:(Leetcode704): 注意条件(low<=high) public int search(int[] nums, int target) { int low=0; in ...

  6. leetcode 数组类型题总结

    1,removeDuplicates(I) int removeDuplicatesI(vector<int>& nums){ // 重新组织数组,同 removeDuplicat ...

  7. leetcode 数组 (python)

    1.题目描述 给定一个范围在  1 ≤ a[i] ≤ n ( n = 数组大小 ) 的 整型数组,数组中的元素一些出现了两次,另一些只出现一次. 找到所有在 [1, n] 范围之间没有出现在数组中的数 ...

  8. leetcode 数组类型题

    // ConsoleApplication1.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <Windows.h& ...

  9. LeetCode——数组篇:659. 分割数组为连续子序列

    659. 分割数组为连续子序列 输入一个按升序排序的整数数组(可能包含重复数字),你需要将它们分割成几个子序列,其中每个子序列至少包含三个连续整数.返回你是否能做出这样的分割? 示例 1: 输入: [ ...

  10. leetcode 数组array

    120. Triangle 给出一个三角形(数据数组),找出从上往下的最小路径和.每一步只能移动到下一行中的相邻结点上. 解法,自底向上 The idea is simple. Go from bot ...

随机推荐

  1. Java换行符

    public static final String NewLineSeparator=System.getProperty("line.separator","\n&q ...

  2. LocalDate test

    import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneId; import java.tim ...

  3. 动态添加表sql

    注意:1.tb_wx_userinfo已经存在,直接复制该表结构 DECLARE @manufacturer_id NVARCHAR(10),@sql NVARCHAR(500) SET @manuf ...

  4. 9 Strings

    1       Strings 1.1  Strings and GStrings Groovy允许你使用2种不同类型的字符串类型,分别是java.lang.String和groovy.lang.GS ...

  5. js实现放大镜效果

    原理: 鼠标在小图片上移动时,通过捕捉鼠标在小图片上的位置,定位大图片的相应位置: 放大镜的移动方向和大图片的移动方向:横向和纵向都是相反,才可以保证同步: 需要元素:大图和小图,存放大图和小图的容器 ...

  6. MySQL 0 学习

    ubuntu  安装mysql  创建用户  以及外部如何可视化连接的   方法   https://www.linuxidc.com/Linux/2017-01/139502.htm 2.3 MyS ...

  7. gRPC框架

    https://blog.csdn.net/shuanger_/article/details/47281381 https://grpc.io/ gRPC是利用通讯协议是HTTP2,序列化用prot ...

  8. 3d Max 2010安装失败怎样卸载3dsmax?错误提示某些产品无法安装

    AUTODESK系列软件着实令人头疼,安装失败之后不能完全卸载!!!(比如maya,cad,3dsmax等).有时手动删除注册表重装之后还是会出现各种问题,每个版本的C++Runtime和.NET f ...

  9. Perf -- Linux下的系统性能调优工具,第 2 部分 特殊用法以及内核调优示例

    https://www.ibm.com/developerworks/cn/linux/l-cn-perf2/ 本文内容简介 之前介绍了 perf 最常见的一些用法,关注于 Linux 系统上应用程序 ...

  10. POJ 3522 ——Slim Span——————【最小生成树、最大边与最小边最小】

    Slim Span Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 7102   Accepted: 3761 Descrip ...