算法刷题模板

BFS和DFS

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;
    }
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值