提交 8c3e41fc 编写于 作者: L liu13

20190106

上级 1f63d60b
package code;
/*
* 160. Intersection of Two Linked Lists
* 题意:求两个链表的交叉点
* 难度:Easy
* 分类:LinkedList
* 思路:两种方法:1.找出两个链表的长度差x,长的先走x步; 2.走完一个链表,走另一个链表,两个cur都走了两个链表长度的和步
* Tips:两种方法的本质是一样的其实,都是找到了步数差,都遍历了两遍
*/
public class lc160 {
public class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA==null||headB==null)
return null;
ListNode curA = headA;
ListNode curB = headB;
while (curA != curB) {
if(curA == null)
curA = headB;
if(curB == null)
curB = headA;
if(curA==curB)
return curA; //别忘了判断一下是否相等
curA = curA.next;
curB = curB.next;
}
return curA;
}
}
package code;
/*
* 169. Majority Element
* 题意:数组中有一个元素出现次数 >len/2 ,找出这个数
* 难度:Easy
* 分类:Array, Divide and Conquer, Bit Maniputation
* 思路:很多种方法, Hashmap 是 O(n), O(n)的。 快排是O(log(n)), O(1)的。最巧妙的办法是 O(n), O(1) 的如下。
* Tips:之所以能够 O(n), O(1) 是因为题目已经给定了数组中一定能找到这个数,该方法充分利用了这一点
*/
public class lc169 {
public int majorityElement(int[] nums) {
int res = nums[0];
int count = 1;
for (int i = 1; i < nums.length ; i++) {
if(nums[i]!=res) // 不是这个数就 --, ==0就用当前数替换res
count--;
else
count++;
if(count==0){
res = nums[i];
count++;
}
}
return res;
}
}
package code;
/*
* 198. House Robber
* 题意:数组最大和,不能选取相邻的两个数
* 难度:Easy
* 分类:Dynamic Programming
* 思路:经典的dp题,记一下
* Tips:时间复杂度为 O(n)
*/
public class lc198 {
public int rob(int[] nums) {
if(nums.length == 0)
return 0;
if(nums.length == 1)
return nums[0];
int[] dp = new int[nums.length];
dp[0] = nums[0];
dp[1] = Math.max(nums[0], nums[1]);
for (int i = 2; i < nums.length ; i++) {
dp[i] = Math.max((dp[i-2] + nums[i]),dp[i-1]); //dp[i] 表示以 0~i 的数组的结果
}
return dp[nums.length-1];
}
}
package code;
/*
* 200. Number of Islands
* 题意:0,1矩阵,求1片区个数
* 难度:Medium
* 分类:Depth-first Search, Breadth-first Search, Union Find
* 思路:两种方法,一种搜索,一种并查集
* Tips:
*/
public class lc200 {
public int numIslands(char[][] grid) {
if(grid.length==0)
return 0;
int count = 0;
for (int i = 0; i < grid.length ; i++) {
for (int j = 0; j < grid[i].length ; j++) {
if( grid[i][j]=='1' ){
count++;
grid[i][j] = '0'; //置0, 下次不用考虑
search(grid,i,j);
}
}
}
return count;
}
public void search(char[][] grid, int i, int j){
if( i>0 && grid[i-1][j]=='1') {
grid[i-1][j] = '0'; //置0, 下次不用考虑
search(grid, i - 1, j);
}
if( j>0 && grid[i][j-1]=='1') {
grid[i][j-1] = '0';
search(grid, i, j-1);
}
if( i+1<grid.length && grid[i+1][j]=='1') {
grid[i+1][j] = '0';
search(grid, i + 1, j);
}
if( j+1<grid[0].length && grid[i][j+1]=='1') {
grid[i][j+1] = '0';
search(grid, i, j+1);
}
return;
}
//并查集
int[] flag;
int count = 0;
public int numIslands2(char[][] grid) {
if(grid.length==0)
return 0;
//初始化, 每个1都是一个island
flag = new int[grid.length*grid[0].length];
for (int i = 0; i < grid.length ; i++) {
for (int j = 0; j < grid[0].length ; j++) {
if(grid[i][j]=='1'){
int id = i*grid[0].length+j;
flag[id] = id;
count++;
}
}
}
for (int i = 0; i < grid.length ; i++) {
for (int j = 0; j < grid[0].length ; j++) {
if(grid[i][j]=='1'){
int id1 = i*grid[0].length+j;
if( i>0 && grid[i-1][j]=='1') { //四个方向都合一下,虽然有些冗余
int id2 = (i-1)*grid[0].length+j;
union(id1, id2);
}
if( j>0 && grid[i][j-1]=='1') {
int id2 = i*grid[0].length+j-1;
union(id1, id2);
}
if( i+1<grid.length && grid[i+1][j]=='1') {
int id2 = (i+1)*grid[0].length+j;
union(id1, id2);
}
if( j+1<grid[0].length && grid[i][j+1]=='1') {
int id2 = i*grid[0].length+j+1;
union(id1, id2);
}
}
}
}
return count;
}
public void union(int id1, int id2){
int flag_id1 = find(id1);
int flag_id2 = find(id2);
if(flag_id1==flag_id2)
return;
else{
flag[flag_id1] = flag[flag_id2]; //把father们的 flag_id 合一起了
count--;
}
}
public int find(int id){ //找到father的flag_id
int res = flag[id];
while(res != id){ //接着往上找father
id = res;
res = flag[id];
}
return res;
}
}
package code;
/*
* 206. Reverse Linked List
* 题意:链表反转
* 难度:Easy
* 分类:Linked List
* 思路:2中方法:设置一个快走一步的快指针,注意赋值操作顺序。还有一种递归的方法。
* Tips:递归的方法有点绕,多看下
*/
public class lc206 {
public class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
public ListNode reverseList(ListNode head) {
ListNode newHead = null; //头节点变成尾节点,最后要指向null
while (head != null) {
ListNode next = head.next;
head.next = newHead;
newHead = head;
head = next;
}
return newHead;
}
public ListNode reverseList2(ListNode head) { //递归
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); //尾递归,操作已经完成,最后返回最后结果罢了
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册