손으로 쓴 제목의 알고리즘 편
11136 단어 javascript 알고리즘 전단
//
const tree = {
data: 1,
left: {
data: 2,
left: {
data: 4,
left: {
data: 8,
},
right: {
data: 9
}
},
right: {
data: 5,
left: {
data: 10,
},
right: {
data: 11
}
}
},
right: {
data: 3,
left: {
data: 6,
left: {
data: 12
}
},
right: {
data: 7
}
}
};
두 갈래 나무의 넓이가 두루 미치다
광도 범람은 각 층을 범람하는 것이다. 위의tree 광도 범람 후의 결과는 [1,2,3,4,5,6,7,8,9,10,11,12]이다.실현 방식은 창고를 통해 옮겨다니는 상태를 부모 노드, 왼쪽 트리, 오른쪽 트리의 순서에 따라 창고를 압축하는 것이다.창고의 꼭대기를 꺼내서 결과 그룹에 저장하고 창고가 비어 있을 때 반복해서 끝냅니다.
코드는 다음과 같습니다.
//
function bfs(tree){
//
let stack = [tree];
let result = [];
while(stack.length){
//
const node = stack.shift();
result.push(node.data);
//
if(node.left){
stack.push(node.left);
}
//
if(node.right){
stack.push(node.right);
}
}
return result;
}
console.log(' ', bfs(tree));
두 갈래 나무가 층층이 두루 다니다
층차 반복은 층마다 하나의 그룹 항목에 저장됩니다.
//
function levelOrder(tree){
const output = [];
let level = 0;
if(level === null){
return output;
}
const visitLoop = (node, level) => {
if(!output[level]){
output[level] = [];
}
output[level].push(node.data);
if(node.left){
visitLoop(node.left, level + 1);
}
if(node.right){
visitLoop(node.right, level + 1);
}
};
visitLoop(tree, 0);
return output;
}
console.log(' ', levelOrder(tree));
두 갈래 나무의 앞줄이 두루 다니다
앞의 순서가 반복되는 순서는 루트에 접근한 다음 왼쪽 트리에 접근하고 오른쪽 트리에 접근하는 것입니다.앞의 순서가 반복된 결과는 [1, 2, 4, 8, 9, 5, 10, 11, 3, 6, 12, 7]이다.창고의 특성을 이용하여 현재 스트리밍 상태를 저장합니다.루트 노드를 초기화하고 창고를 먼저 압수합니다.매번 순환에서 창고 꼭대기를 꺼내 결과 그룹에 저장하고, 오른쪽 나무 창고가 있으면 왼쪽 나무 창고가 있습니다.
//
function preOrder(tree){
let stack = [tree];
let result = [];
let node;
while(stack.length){
let node = stack.pop();
result.push(node.data);
if(node.right){
stack.push(node.right);
}
if(node.left){
stack.push(node.left);
}
}
return result;
}
console.log(' ', preOrder(tree));
앞의 순서가 두루 반복되는 귀속 실현
//
function preOrderRcs(tree){
let result = [];
const visitLoop = function(node){
result.push(node.data);
if(node.left){
result.concat(visitLoop(node.left));
}
if(node.right){
result.concat(visitLoop(node.right));
}
};
visitLoop(tree);
return result;
}
console.log(' - ', preOrderRcs(tree));
두 갈래 나무에 차례대로
중간 순서는 왼쪽 트리를 먼저 방문하고, 루트를 방문하고, 마지막으로 오른쪽 트리를 방문합니다.중순 역행 결과는 [8, 4, 9, 2, 10, 5, 11, 1, 12, 6, 3, 7]이다.중순 반복 비귀속 실현은 역추적 알고리즘을 사용했다.
회소법(back tracking)(탐색과 회소법)은 우수한 것을 선택하는 검색법으로 탐색법이라고도 부른다. 우수한 조건에 따라 앞으로 검색하여 목표를 달성한다.그러나 어떤 단계를 탐색했을 때 원래 선택이 좋지 않거나 목표에 도달하지 못하면 한 걸음 물러서서 다시 선택하는 기술을 소급법이고 소급 조건을 만족시키는 어떤 상태를 소급점이라고 한다.
반복되지 않거나 창고를 이용하여 반복되는 순서를 저장하고 현재 반복되는 노드를 변수로 저장합니다.스트리밍 조건: 창고가 비어 있지 않거나 현재 노드가 비어 있지 않으며 현재 노드가 창고에 저장됩니다. 순서대로 왼쪽 트리를 창고에 넣습니다. 왼쪽 트리가 존재하지 않을 때 창고 꼭대기에서 튀어나온 원소가 결과 그룹에 저장됩니다. 만약에 튀어나온 원소가 오른쪽 트리가 있다면 오른쪽 트리는 현재 스트리밍 노드이고 창고에 저장됩니다.
//
function inOrder(tree){
const stack = [];
const result = [];
//
let node = tree;
while(stack.length || node){
// ,
if(node){
stack.push(node);
node = node.left;
}else{
// ,
const current = stack.pop();
//
result.push(current.data);
// ,
if(current.right){
node = current.right;
}
}
}
return result;
}
console.log(' ', inOrder(tree));
//
function inOrderRcs(tree){
let result = [];
const visitLoop = function(node){
if(node.left){
result.concat(visitLoop(node.left));
}
result.push(node.data);
if(node.right){
result.concat(visitLoop(node.right));
}
};
visitLoop(tree);
return result;
}
console.log(' - ', inOrderRcs(tree));
두 갈래 나무 뒤에 차례대로
먼저 왼쪽 트리를 훑어보고 오른쪽 트리를 훑어보고 마지막에 뿌리를 훑어본다.뒷순서 역행 결과는 [8, 9, 4, 10, 11, 5, 2, 12, 6, 7, 3, 1]이다.
스트리밍 순서를 저장하는 창고와 현재 스트리밍 노드를 저장하는 것을 제외하고 모든 노드에touched 속성을 추가합니다.현재 노드에 왼쪽 트리가 있을 때 순서대로 창고를 누비고, 현재 노드 터치는left로 설정합니다.현재 노드에 오른쪽 트리가 있을 때 순서대로 창고를 누비고, 현재 터치ed는false로 설정합니다.만약 잎 노드나 좌우 나무를 모두 훑어보았다면 결과 그룹에 저장합니다.현재 역행 노드를 창고 꼭대기 요소로 설정합니다.
//
function postOrder(tree){
const stack = [tree];
const result = [];
let node = tree;
while(stack.length){
// ,
if(node.left && !node.touched){
node.touched = 'left';
node = node.left;
stack.push(node);
continue;
}
// ,
if(node.right && node.touched !== 'right'){
node.touched = 'right';
node = node.right;
stack.push(node);
continue;
}
//
const current = stack.pop();
result.push(current.data);
//
node = stack[stack.length - 1];
}
return result;
}
console.log(' ', postOrder(tree))
// -
function postOrderRcs(tree){
let result = [];
const visitLoop = function(node){
if(node.left){
result.concat(visitLoop(node.left));
}
if(node.right){
result.concat(visitLoop(node.right));
}
result.push(node.data);
};
visitLoop(tree);
return result;
}
console.log(' - ', postOrderRcs(tree))
두 갈래 나무의 최대 깊이
//
function maxDepth(tree){
if(tree === null){
return 0;
}
let res = 0;
const visitLoop = (node, level) => {
if(!node){
return 0;
}
if(!node.left && !node.right){
res = Math.max(res, level);
}
if(node.left){
visitLoop(node.left, level + 1);
}
if(node.right){
visitLoop(node.right, level + 1);
}
};
visitLoop(tree, 1);
return res;
}
console.log(' ', maxDepth(depthTree));
이분 검색
function binarySearch(nums, target){
if(!nums.length){
return -1;
}
let start = 0
let end = nums.length - 1;
let mid;
while(start <= end){
let mid = Math.floor((start + end) /2);
if(target === nums[mid]){
return mid;
}
if(target < nums[mid]){
end = mid - 1;
}
if(target > nums[mid]){
start = mid + 1;
}
}
return -1;
}
console.log(' ', binarySearch([-1,0,3,5,9,12], 9));
빠른 정렬
두 가지 절차로 나뉜다.
//
function quickSort(nums = []){
const swap = (nums, i ,j) => {
const temp = nums[j];
nums[j] = nums[i];
nums[i] = temp;
};
//
const partition = (nums, i, j) => {
let left = i;
let right = j;
let mid = Math.floor((right + left)/2);
//
while(left <= right){
while(nums[left] < nums[mid]){
left++;
}
while(nums[right] > nums[mid]){
right --;
}
if(left <= right){
swap(nums, left, right);
left++;
right --;
}
}
return left;
};
//
const quickSortHandler = (nums, left, right) => {
let index;
//
if(nums.length > 1){
index = partition(nums, left, right);
if(left < index - 1){
quickSortHandler(nums, left, index - 1);
}
if(index < right){
quickSortHandler(nums, index, right);
}
}
return nums;
};
quickSortHandler(nums, 0, nums.length - 1);
return nums;
}
console.log(' ', quickSort([5,1,1,2,0,0]));
K위
빠른 정렬 후 그룹 중arr.length-k의 원소를 찾아내면 됩니다.
최대 공통 접두어
//
function longestCommonPrefix(strs = []){
if(!strs.length){
return '';
}
let res = strs[0];
for(let i = 1; i < strs.length; i++){
let j = 0;
for(;j < strs[i].length; j++){
if(strs[i][j] !== res[j]){
break;
}
}
res = res.substring(0, j);
if(!res){
return '';
}
}
return res;
}
console.log(' ', longestCommonPrefix(["flower","flow","flight"]));
중복된 문자가 없는 가장 긴 문자열
//
function lengthOfLongestSubstring(s){
let max = 0;
const arr = [];
if(!s){
return '';
}
for(let i = 0; i< s.length; i++){
if(arr.find(item => item ===s[i])){
let index = arr.findIndex(item => item === s[i]);
arr.splice(0, index + 1);
}
arr.push(s[i]);
max = Math.max(arr.length, max);
}
return max;
}
console.log(' ', lengthOfLongestSubstring('abcabcbb'));
참고 문장: 두 갈래 나무가 두루 다니다javascript 데이터 구조와 알고리즘 학습