算法刷题模板

来源:互联网 发布:淘宝新店铺如何运营 编辑:程序博客网 时间: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;    }
原创粉丝点击