算法刷题模板
来源:互联网 发布:淘宝新店铺如何运营 编辑:程序博客网 时间:2024/05/20 22:40
BFS和DFS
- 题目地址:http://www.lintcode.com/problem/number-of-islands/
public void dfs(boolean[][] grid,boolean[][] vis,int i,int j){// vis的访问放在最后面 if(i<0||i>=grid.length||j<0||j>=grid[0].length) return; if(grid[i][j]==true&&vis[i][j]==false){ vis[i][j]=true; dfs(grid,vis,i-1,j); dfs(grid,vis,i+1,j); dfs(grid,vis,i,j-1); dfs(grid,vis,i,j+1); } else return; } public void bfs(boolean[][] grid,boolean[][] vis,int i,int j){ Vector<Point> record=new Vector<>(); int[] delta_x=new int[]{-1,1,0,0}; int[] delta_y=new int[]{0,0,-1,1}; record.add(new Point(i, j)); while(record.size()>0){ Point p=record.remove(0); vis[p.x][p.y]=true; for(int index=0;index<4;index++){ int new_x=p.x+delta_x[index]; int new_y=p.y+delta_y[index]; if(new_x>=0&&new_x<grid.length&&new_y>=0&&new_y<grid[0].length&&vis[new_x][new_y]==false&&grid[new_x][new_y]==true){ record.add(new Point(new_x,new_y)); } } } } public int numIslands(boolean[][] grid) { // Write your code here boolean[][] vis=new boolean[grid.length][grid[0].length]; int cnt=0; for(int i=0;i<grid.length;i++){ for(int j=0;j<grid[0].length;j++){ if(grid[i][j]==true&&vis[i][j]==false){ cnt++;// dfs(grid,vis,i,j); bfs(grid,vis,i,j); } } } return cnt; }
BFS
题目地址:http://www.lintcode.com/problem/binary-tree-level-order-traversal/
public List<List<Integer>> levelOrder(TreeNode root) { // write your code here List result = new ArrayList(); if(root== null) return result; Queue<TreeNode> queue = new LinkedList<TreeNode>();//linkedlist 是queue的子类 queue.add(root); while(!queue.isEmpty()){ ArrayList<Integer>level = new ArrayList<Integer>(); int size = queue.size(); for(int i=0; i< size;i++){ TreeNode head = queue.poll(); level.add(head.val); if(head.left!=null){ queue.offer(head.left); } if (head.right!=null){ queue.offer(head.right); } } result.add(level); } return result; }
了解一下递归的写法
问题描述:求解Fibonacci数列的第n个位置的值?指的是这样一个数列:1、1、2、3、5、8、13、21、……
解法1:传统的递归做法,当n比较大的时候比较费时间
public int fib(int index){ if(index==1||index==2){ return 1; }else{ return fib(index-1)+fib(index-2); } }
解法2:在传统的做法上加上了一个记录数组,节省了一定时间
public int fibona(int index,int[] nums){ if(nums[index]!=0) return nums[index]; if(index==1||index==2){ nums[index]=1; return 1; }else{ nums[index]=fib(index-1)+fib(index-2) return nums[index]; } }
解法3:相当与动态规划的做法,从边界向目标一边记录一边遍历。
public int fibonacci(int index){ int a=1,b=1,result=0; for(int i=0;i<=index;i++){ if(i<=2) result=a; else{ result=a+b; a=b; b=result; } } return result; }
对于回溯问题(递归)的通用解法
这个解法可以应用于很多回溯问题,比如Subsets, Permutations, and Combination Sum。
Subsets : https://leetcode.com/problems/subsets/
解法1:把问题分成很多子问题。(推荐这种,因为方便处理后面的subsets II )
public List<List<Integer>> subsets(int[] nums) { List<List<Integer>> list = new ArrayList<>(); Arrays.sort(nums); backtrack(list, new ArrayList<>(), nums, 0); return list;}private void backtrack(List<List<Integer>> list , List<Integer> tempList, int [] nums, int start){ list.add(new ArrayList<>(tempList)); for(int i = start; i < nums.length; i++){ tempList.add(nums[i]); backtrack(list, tempList, nums, i + 1); tempList.remove(tempList.size() - 1); }}
解法2:对于每个数都有放入和不放入两种状态,从左到右遍历数组,枚举每种状态。
public void backstrack2(List<List<Integer>> list,List<Integer> temp,int index,int[] nums){ if(index==nums.length){ list.add(new ArrayList<>(temp)); return; }else{ temp.add(nums[index]); backstrack2(list, temp, index+1, nums); temp.remove(temp.size()-1); backstrack2(list, temp, index+1, nums); } } public List<List<Integer>> subsets(int[] nums) { Arrays.sort(nums); List<List<Integer>> list=new ArrayList<>(); backstrack2(list, new ArrayList<>(), 0, nums); return list; }
Subsets II (contains duplicates) : https://leetcode.com/problems/subsets-ii/
public List<List<Integer>> subsetsWithDup(int[] nums) { List<List<Integer>> list = new ArrayList<>(); Arrays.sort(nums); backtrack(list, new ArrayList<>(), nums, 0); return list;}private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, int start){ list.add(new ArrayList<>(tempList)); for(int i = start; i < nums.length; i++){ if(i > start && nums[i] == nums[i-1]) continue; // skip duplicates tempList.add(nums[i]); backtrack(list, tempList, nums, i + 1); tempList.remove(tempList.size() - 1); }}
Permutations : https://leetcode.com/problems/permutations/
public List<List<Integer>> permute(int[] nums) { List<List<Integer>> list = new ArrayList<>(); // Arrays.sort(nums); // not necessary backtrack(list, new ArrayList<>(), nums); return list;}private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums){ if(tempList.size() == nums.length){ list.add(new ArrayList<>(tempList)); } else{ for(int i = 0; i < nums.length; i++){ if(tempList.contains(nums[i])) continue; // element already exists, skip tempList.add(nums[i]); backtrack(list, tempList, nums); tempList.remove(tempList.size() - 1); } }}
Permutations II (contains duplicates) : https://leetcode.com/problems/permutations-ii/
public List<List<Integer>> permuteUnique(int[] nums) { List<List<Integer>> list = new ArrayList<>(); Arrays.sort(nums);//不能忘记这步 backtrack(list, new ArrayList<>(), nums, new boolean[nums.length]); return list;}private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, boolean [] used){ if(tempList.size() == nums.length){ list.add(new ArrayList<>(tempList)); } else{ for(int i = 0; i < nums.length; i++){ //如果这个位置已经被访问过 //两个位置的数如果是一样的,那么只有前面的数用过之后,采用现在这个数,这样就保证了2,2,只有有一种组合 if(used[i] || i > 0 && nums[i] == nums[i-1] && !used[i - 1]) continue; used[i] = true; tempList.add(nums[i]); backtrack(list, tempList, nums, used); //回溯回来要修改两个地方 used[i] = false; tempList.remove(tempList.size() - 1); } }}
Combination Sum : https://leetcode.com/problems/combination-sum/
public List<List<Integer>> combinationSum(int[] nums, int target) { List<List<Integer>> list = new ArrayList<>(); Arrays.sort(nums); backtrack(list, new ArrayList<>(), nums, target, 0); return list;}private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, int remain, int start){ if(remain < 0) return; else if(remain == 0) list.add(new ArrayList<>(tempList)); else{ for(int i = start; i < nums.length; i++){ tempList.add(nums[i]); backtrack(list, tempList, nums, remain - nums[i], i); // not i + 1 because we can reuse same elements tempList.remove(tempList.size() - 1); } }}
Combination Sum II (can’t reuse same element) : https://leetcode.com/problems/combination-sum-ii/
public List<List<Integer>> combinationSum2(int[] nums, int target) { List<List<Integer>> list = new ArrayList<>(); Arrays.sort(nums); backtrack(list, new ArrayList<>(), nums, target, 0); return list;}private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, int remain, int start){ if(remain < 0) return; else if(remain == 0) list.add(new ArrayList<>(tempList)); else{ for(int i = start; i < nums.length; i++){ if(i > start && nums[i] == nums[i-1]) continue; // skip duplicates tempList.add(nums[i]); backtrack(list, tempList, nums, remain - nums[i], i + 1); tempList.remove(tempList.size() - 1); } }}
Palindrome Partitioning : https://leetcode.com/problems/palindrome-partitioning/
public List<List<String>> partition(String s) { List<List<String>> list = new ArrayList<>(); backtrack(list, new ArrayList<>(), s, 0); return list;}public void backtrack(List<List<String>> list, List<String> tempList, String s, int start){ if(start == s.length()) list.add(new ArrayList<>(tempList)); else{ for(int i = start; i < s.length(); i++){ if(isPalindrome(s, start, i)){ tempList.add(s.substring(start, i + 1)); backtrack(list, tempList, s, i + 1); tempList.remove(tempList.size() - 1); } } }}public boolean isPalindrome(String s, int low, int high){ while(low < high) if(s.charAt(low++) != s.charAt(high--)) return false; return true;}
链表
Reverse Linked List
https://leetcode.com/problems/reverse-linked-list/description/
Your solution
public ListNode reverseList(ListNode head) { // write your code here ListNode prev =null; while(head!=null){ ListNode temp= head.next; head.next = prev; prev =head; head=temp; } return prev; }
My solution
public ListNode reverseList(ListNode head) { ListNode dummy=new ListNode(0); dummy.next=head; ListNode tail=dummy,next=head; ListNode flag=dummy; ListNode temp=null; while(next!=null){ temp=next.next;//assign new next in temp if(tail.next==next) { flag=next; next=temp; continue; } next.next=tail.next; tail.next=next;//insert next=temp;// update next } flag.next=temp; return dummy.next; }
Reverse Linked List II
https://leetcode.com/problems/reverse-linked-list-ii/description/
public ListNode reverseBetween(ListNode head, int m, int n) { ListNode dummy=new ListNode(0); dummy.next=head; ListNode tail=dummy; while(m>1){ m--; n--; tail=tail.next; } ListNode next=tail.next; ListNode flag=tail.next; ListNode temp=null; while(n>0){ n--; temp=next.next;//store next new node if(tail.next==next) { flag=next;//store the final tail node next=temp; continue; } next.next=tail.next; tail.next=next; next=temp; } flag.next=temp; return dummy.next; }
Reverse Nodes in k-Groups
https://leetcode.com/problems/reverse-nodes-in-k-group/description/
对每k个都标记好head和tail,然后把head后面的元素,一个一个拿下来放到传入到tail的后面
public ListNode reverseKGroup(ListNode head, int k) { if(head==null||head.next==null||k<2) return head; ListNode dummy=new ListNode(0); dummy.next=head; ListNode prev=dummy,tail=dummy; while(true){ int cnt=k; while(cnt!=0&&tail!=null){ tail=tail.next; cnt--; } if(tail==null) break; head=prev.next; while(prev.next!=tail){ ListNode temp=prev.next;//Assign prev.next=temp.next;//Delete temp.next=tail.next; tail.next=temp;//Insert } prev=head; tail=head; } return dummy.next; }
排序
对于链表的排序
http://www.lintcode.com/en/problem/sort-list/
解法1:快速排序
public ListNode part(ListNode head,ListNode tail){ int key=head.val; ListNode slow=head,fast=head.next; while(fast!=tail){ if(fast.val<key){ slow=slow.next; int temp=fast.val; fast.val=slow.val; slow.val=temp; } fast=fast.next; } int temp=head.val; head.val=slow.val; slow.val=temp; return slow; } public void quick(ListNode head,ListNode tail){ if(head==tail) return; ListNode pivot=part(head, tail); quick(head, pivot); quick(pivot.next, tail); } public ListNode sortList(ListNode head) { // write your code here quick(head, null); return head; }
解法2:归并排序
public ListNode sortList(ListNode head){ if(head==null||head.next==null) return head; ListNode head1=getMid(head); head=sortList(head); head1=sortList(head1); return merge(head,head1); } public ListNode getMid(ListNode head){ ListNode fast=head.next,slow=head.next,prev=head; while(fast!=null){ if(fast==null) break; fast=fast.next; if(fast==null) break; fast=fast.next; prev=slow; slow=slow.next; } prev.next=null;//this is very important return slow; } public ListNode merge(ListNode head1,ListNode head2){ ListNode newNode= new ListNode(-1); ListNode tail=newNode; while(head1!=null&&head2!=null){ if(head1.val<=head2.val){ tail.next=head1; head1=head1.next; }else{ tail.next=head2; head2=head2.next; } tail=tail.next; tail.next=null;//this is very important } if(head1!=null) tail.next=head1; if(head2!=null) tail.next=head2; return newNode.next; }
阅读全文
0 0
- 算法刷题模板
- poj2421kruskal算法模板题
- Kruskal 算法模板题
- POJ1125Floyd-warshall算法模板题
- 【Eternallyc】模板题-Floyd算法
- ST算法模板题poj3264
- HDOJ1083 匈牙利算法模板题
- HDOJ2063(匈牙利算法模板题)
- 【模板】LCA Tarjan算法 (模板题:洛谷P3379)
- 【模板】匈牙利算法 二分图最大匹配题模板
- poj 1330lca模板题离线算法
- 图论---POJ 3660 floyd 算法(模板题)
- 最短路+hdu+spfa算法模板题
- POJ - 3974 Palindrome(Manacher算法模板题)
- hdu 5145 莫队算法模板题
- 匈牙利算法模板题 hdu 1150
- 扩展欧几里得算法模板题 zoj 3609
- hdu 1711 KMP算法模板题
- hdu 6149 Valley Numer II (状态压缩dp)
- 欢迎使用CSDN-markdown编辑器
- Android OpenGL ES 绘图 -- 缩放、平移、旋转
- Spark之shuffle性能优化
- svn提交的坑
- 算法刷题模板
- 微信小程序自定义字体及自定义图标问题说明
- 1291:水仙花数
- Map
- CSDN如何转载别人的文章
- Springboot框架配置远程Tomcat服务器以及本地Tomcat服务器进行远程debug调试
- poj 1603 Risk(floyd)
- css中position相对定位和绝对定位(relative,absolute)详解
- 使用apidocJs快速生成在线文档