LeetCode解題報告—— Reverse Nodes in k-Group && Sudoku Solver
1. Reverse Nodes in k-Group
Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.
k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.
Example:
Given this linked list: 1->2->3->4->5
For k = 2, you should return: 2->1->4->3->5
For k = 3, you should return: 3->2->1->4->5
Note:
- Only constant extra memory is allowed.
- You may not alter the values in the list‘s nodes, only nodes itself may be changed.
思路:嘗試遍歷鏈表,根據索引關系來逆置指定部分,結果發現復雜無比,gg。還是看了下解析,置頂的方法是用遞歸來解題。其基本想法是對於找到的k個節點逆置,然後對剩下的節點作相同處理。雖然不是很高效但是卻非常通俗易懂。
代碼:
public ListNode reverseKGroup(ListNode head, int k){
ListNode cur=head;
int count=0;
while(cur!=null && count<k){
cur=cur.next;
count++;
}
if(count==k){
cur=reverseKGroup(cur, k); //標記1
//這裏的逆轉邏輯是依次將第一個移動到相應後面的位置,cur始終指向這個位置的下一個
while(count-- > 0){
ListNode temp=head.next; //將當前頭結點的下一個賦給temp
head.next=cur; //cur指向下一組逆轉置後的頭結點(第一個幾點),將head移動到逆置後的位置,也就是cur前面
cur=head; //因為head已經移動好了,接下來移動temp的話,應該是移動到head的前面,所以需要將cur指向head
head=temp;//將原先第二個節點temp置為新的head,循環往後移,直至移動了k個
}
//逆置完成後cur應該指向當前k個節點中的第一個,
//需要將其賦給head返回,標記1處的cur才能指向其後面k個節點逆置後的第一個節點
head=cur;
}
return head;
}
2. Sudoku Solver
Write a program to solve a Sudoku puzzle by filling the empty cells.
A sudoku solution must satisfy all of the following rules:
- Each of the digits
1-9
must occur exactly once in each row. - Each of the digits
1-9
must occur exactly once in each column. - Each of the the digits
1-9
must occur exactly once in each of the 93x3
sub-boxes of the grid.
Empty cells are indicated by the character ‘.‘
.
A sudoku puzzle...
...and its solution numbers marked in red.
Note:
- The given board contain only digits
1-9
and the character‘.‘
. - You may assume that the given Sudoku puzzle will have a single unique solution.
- The given board size is always
9x9
.
思路:看了下discussion,發現有多種解題方法,比如DFS或者Backtracing,也有算法大神給出了很厲害的解法。還是選擇較為簡單的Backtracing方法來考慮。其基本思路是:
1. 遍歷整個數獨,對於空缺的部分,嘗試用1到9填充。
2. 填充前先判斷當前位置所對應的行和列,以及所在的3*3矩陣有沒有整個1~9數字,如果有則跳過判斷1~9中的下一個。
3. 填充好了後,將當前矩陣作為新的輸入重復步驟1,2,3,這樣遞歸,如果有一層如果1~9都填不進去則表示數獨不合法,上層填的有誤,需返回false到上層重置上層填的數字。如果順利遞歸到最底層,也就是填好了整個數獨,因為每次的賦值標準是數獨合法,所以填好的數獨也是合法的,故返回true。
代碼:
public class Solution {
public void solveSudoku(char[][] board) {
if(board == null || board.length == 0)
return;
solve(board);
}
public boolean solve(char[][] board){
for(int i = 0; i < board.length; i++){
for(int j = 0; j < board[0].length; j++){
if(board[i][j] == ‘.‘){
for(char c = ‘1‘; c <= ‘9‘; c++){//trial. Try 1 through 9,註意這裏直接c++就可以取到字符數字的下一個
if(isValid(board, i, j, c)){
board[i][j] = c; //Put c for this cell
if(solve(board))
return true; //If it‘s the solution return true
else
board[i][j] = ‘.‘; //Otherwise go back
}
}
return false; // 如果在某一層遍歷了1~9後還是沒有返回true則表示無解,上層填充的數字有問題,返回false到上層將相應的字符數字改回為‘.‘
}
}
}
return true;// 如果可以順利通過所有遍歷,因為每次的賦值標準是數獨合法,所以順利遍歷之後數獨也是合法的,故返回true
}
private boolean isValid(char[][] board, int row, int col, char c){
for(int i = 0; i < 9; i++) {
if(board[i][col] != ‘.‘ && board[i][col] == c) return false; //check row
if(board[row][i] != ‘.‘ && board[row][i] == c) return false; //check column
if(board[3 * (row / 3) + i / 3][ 3 * (col / 3) + i % 3] != ‘.‘ &&
board[3 * (row / 3) + i / 3][3 * (col / 3) + i % 3] == c) return false; //check 3*3 block,這裏的check 3*3 block還是很有意思的
}
return true;
}
}
LeetCode解題報告—— Reverse Nodes in k-Group && Sudoku Solver