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. AnnotationConfigApplicationContext

    package com.test; import java.io.IOException; import java.io.InputStream; import java.net.URL; impor ...

  2. spring boot 系统启动时运行代码(1)-@PostConstruct

    Application.java import org.springframework.boot.SpringApplication; import org.springframework.boot. ...

  3. uva 133解题报告

    题目描述 为了缩短领救济品的队伍,NNGLRP决定了以下策略:每天所有来申请救济品的人会被放在一个大圆圈,面朝里面.选定一个人为编号 1 号,其他的就从那个人开始逆时针开始编号直到 N.一个官员一开始 ...

  4. mysql查询过去12个月的数据统计

    SELECT DATE_FORMAT( FROM_UNIXTIME( t.`created_at`, '%Y-%m-%d %H:%i:%S' ), '%Y-%m' ) MONTH, count(t.c ...

  5. java——链表、链表栈 LinkedListStack、链表队列 LinkedListQueue

    LikedList: package Date_pacage; public class LinkedList<E> { public static void main(String[] ...

  6. webstorm中.vue报错(es6语法报错)-转

    1.webstorm中es6语法报错,解决方法: 打开 Settings => Languages & Frameworks => Javascript把 Javascript L ...

  7. 办公开发环境(外接显示屏,wifi热点)

    笔记本电脑怎样外接显示器 https://jingyan.baidu.com/article/3c48dd34495247e10ae35879.html?qq-pf-to=pcqq.c2c 怎样在Wi ...

  8. RTT设备与驱动之串口

    有一般收发.中断方式.DMA方式: rt_device_t rt_device_find(const char* name); rt_err_t rt_device_open(rt_device_t ...

  9. 主席树-----动态开点,不hash

    POJ - 2104 第k大 #include <cstdio> #include <cstdlib> #include <cstring> #include &l ...

  10. my___sublime Text配置

    sublime text 备份 插件下载 http://www.cnblogs.com/457220157-FTD/p/5546545.html https://www.jianshu.com/p/3 ...