1. 程式人生 > >二分查詢的巧妙運用(C++)

二分查詢的巧妙運用(C++)

一、二分查詢 1、查詢無序陣列中的任意一個區域性最小值 區域性最小值:arr長度為1時,arr[0]是區域性最小。arr的長度為N(N>1)時,如果arr[0]<arr[1],那麼arr[0]是區域性最小;如果arr[N-1]<arr[N-2],那麼arr[N-1]是區域性最小;如果0<i<N-1,既有arr[i]<arr[i-1]又有arr[i]<arr[i+1],那麼arr[i]是區域性最小。 解法:二分查詢。先檢視左右兩邊是不是區域性最小。都不是則區域性最小一定在中間,於是檢視mid處是不是,若不是則區域性最小要麼在其左邊要麼在其右邊,判斷出在左邊還是在右邊,繼續二分查詢即可。 class Solution { public
: intgetLessIndex(vector<int> arr) { intlength = arr.size(); if(length ==0) return-1; if(length ==1) return0; if(arr[0] < arr[1]) return0; if(arr[length-1] < arr[length-2]) returnlength-1; intstart =0,end = length-1; intmid = (start+end)/2; while(1) { if(arr[mid] < arr[mid+
1] && arr[mid] < arr[mid-1]) returnmid; elseif(arr[mid] > arr[mid-1]) { end = mid; mid = (start+end)/2; } else{ start = mid; mid = (start+end)/2; }             } } };
2、對於一個有序陣列arr,再給定一個整數num,請在arr中找到num這個數出現的最左邊的位置 解法:二分查詢。要注意當arr[mid]大於或等於num時都要轉向左半部查詢。查詢停止條件很重要。 class
LeftMostAppearance { public: intfindPos(vector<int> arr,intn,intnum) { intres = -1; intstart =0,end = n-1; intmid = (start+end)/2; while(start <= end) { if(arr[mid] < num) { start = mid+1;                } elseif(arr[mid] == num) { res = mid; end = mid-1; } else{ end = mid-1; } mid = (start+end)/2; } returnres; } };
3、有序迴圈陣列arr,返回arr中的最小值 有序迴圈陣列:1,2,3,4,5      2,3,4,5,1      3,4,5,1,2     4,5,1,2,3      5,1,2,3,4 解法:①判斷最左和最右的關係。確定陣列是有序的還是迴圈過的。            ②判斷最左和中間的關係。確定最小值位於左半部還是右半部。            ③最左大於中間,在左半部,end = mid;最左小於或等於中間,在右半部,但是start的更新不同,小於時        start=mid,等於時start=mid+1. class MinValue { public: int getMin(vector<int> arr, int n) { if (n == 0) { return -1;         } int start = 0,end = n-1; int mid = start + (end-start)/2; if (arr[start] < arr[end]) { return arr[start];         }         else if (arr[start] > arr[end]) { while (start != end) { if (arr[start] > arr[mid]) {                         end = mid;                 } else if(arr[start] < arr[mid]){                     start = mid;                 } else {                     start = mid+1;                 }                 mid = start + (end-start)/2;             } return arr[start];                     } else { int min = arr[start];            for (int i = 0;i < n;i++) { if (arr[i] < min)                     min = arr[i];             } return min;         }             } }; 4、返回最左原位。即對於有序陣列arr,其中不含有重複元素,請找到滿足arr[i]==i條件的最左的位置 解法:直接判斷mid是否滿足,arr[mid] >= mid都說明只有左半部有可能出現滿足條件的元素,arr[mid] < mid說明只有右半部有可能。
classFind { public: intfindPos(vector<int> arr,intn) { intres = -1; if(n ==0) returnres; intstart =0,end = n-1; intmid = -1; if(arr[start] == start) returnstart; while(start <= end) {             mid = start + (end-start)/2
if(arr[mid] == mid) { res = mid; end = mid-1; } elseif(arr[mid] > mid)  end = mid-1; else  start = mid +1; } returnres; } }; 5、統計完全二叉樹的結點總數 要求:時間複雜度低於O(N)。 解法:二分查詢。 ①先遍歷到二叉樹左子樹最左邊的結點和右子樹最左邊的結點,統計左右子樹的深度。 ②若左右子樹深度相同,說明左子樹是滿二叉樹,若左子樹深度大於右子樹深度,說明右子樹是滿二叉樹。 ③遞迴地進行上述過程。 classCountNodes { public: intcount(TreeNode* root) { if(!root) return0; intleftDepth =0

相關推薦

二分查詢巧妙運用C++

一、二分查詢 1、查詢無序陣列中的任意一個區域性最小值 區域性最小值:arr長度為1時,arr[0]是區域性最小。arr的長度為N(N>1)時,如果arr[0]<arr[1],那麼arr[0]是區域性最小;如果arr[N-1]<arr[N-2],那麼arr

程式設計技巧--位運算的巧妙運用1

 作者:yunyu5120              這是我的這一系列文章的第一篇,主要講述我學習過程中積累的一些程式設計技巧,由於我也是一個初學者,高手莫笑。這一篇主要講解位運算的基礎知識魚與其簡單應用,我主要以C/C++語言講述,其他語言可以類推。如果你已經對位運算基礎和應用十分熟悉,那麼本文並不適

leetcode 刷題題解c++ 1.Two Sum hash表,排序+二分查詢

題目描述: Given an array of integers, find two numbers such that they add up to a specific target number. The function twoSum should return i

資料結構實現 4.1:集合_基於二分搜尋樹實現C++版

資料結構實現 4.1:集合_基於二分搜尋樹實現(C++版) 1. 概念及基本框架 2. 基本操作程式實現 2.1 增加操作 2.2 刪除操作 2.3 查詢操作 2.4 其他操作 3. 演算法複雜度分析

二分查詢-陣列實現小trick

template<typename T> int binarySearch(T arr[], int n, T target){ int l = 0, r = n-1;       //在[l...r]範圍內尋找targetwhile(l <= r){          

C++:二叉查詢樹實現——遍歷操作

     建立好二叉樹,有時候我們需要對整個二叉樹錦星遍歷,即輸出二叉樹的所有結點元素。理論上,遍歷的方式有無數種,順序可以自己任意選定,但是絕大部分遍歷方式在實際中並沒有用處,比較有用的的遍歷方式有兩種:廣度優先遍歷、深度優先遍歷。 (1)廣度優先遍歷        

二叉搜尋樹的查詢、插入與刪除操作Binary Search Tree, Search, Insert, DeleteC++

一、概念     設 x 是二叉搜尋樹中的一個結點。如果 y 是 x 左子樹中的一個結點,那麼 y.key ≦ x.key。如果 y 是 x 右子樹中的一個結點,那麼 y.key ≧ x.key。  

在楊氏矩陣中查詢一個數C語言實現

  分析:楊氏矩陣的特點是:這個矩陣中的數字從左到右是遞增的,從上到下也是遞增的。知道了這個特點就好寫程式了。如有以下矩陣:     2 3 4  3 4 5     4 5 6   &nb

六大排序演算法與常見的兩大查詢演算法彙總C語言

六大排序演算法程式如下: #include<stdio.h> /*void Bubblesort(int arry[],int len)//氣泡排序演算法 { int i,j; for(i=0;i<len-1;i++) { for(j=i+1;j<le

HDU 4614 Vases and Flowers 二分查詢+線段樹區間更新

  Alice is so popular that she can receive many flowers everyday. She has N vases numbered from 0 to N-1. When she receive some flowers

二分查詢模板總結遞迴與迴圈遍歷兩個版本

二分查詢: 思路: 在有序*陣列***a[]中查詢K 1,不斷分割 。 2 用中間值去比較。 ====================嘗試比較下面兩種,得到遞迴函式的寫法=========

GIS演算法運用C#自帶的函式繪製五角星和多邊形C#

前言: 當我們敲下第一行程式碼向計算機世界說一句—–Hello World 我們就打開了一扇通往計算機世界的大門。 計算機的世界總是充滿著未知和挑戰, 當我們的程式碼第一次出現在漆黑的控制檯; 當我們第一次實現和計算機的互動; 當我們第一次完成自己的

二分查詢字首和洛谷1314聰明的質監員NOIP2011提高組

小T 是一名質量監督員,最近負責檢驗一批礦產的質量。這批礦產共有 n 個礦石,從 1到n 逐一編號,每個礦石都有自己的重量 wi 以及價值vi 。檢驗礦產的流程是: 1 、給定m 個區間[Li,Ri]; 2 、選出一個引數 W; 3 、對於一個區間[Li,Ri],計算礦石在這

C#日誌接口請求響應時間

ide test isnull pty directory pps 請求方式 rri == 日誌接口響應時間,記錄接口請求信息,響應結果以及響應時間等。可以清楚的分析和了解接口現在。 如果一個一個地在接口下面做日誌,那不是我們想要的結果。所以,我們選擇做一個特性來控制接口要

LeetCode | Reverse Words in a StringC#

++ style str blog cnblogs count item leetcode string 題目: Given an input string, reverse the string word by word. For example,Given s = "

算法 - 求一個數組的最長遞減子序列C++

str log bst article subst else from return ear //************************************************************************************

2~62位任意進制轉換c++

rtmp end iostream 思路 [0 代碼 () objc blog 進制轉換的符號表為[0-9a-zA-Z],共61個字符,最大可表示62進制。 思路是原進制先轉換為10進制,再轉換到目標進制。 疑問:   對於負數,有小夥伴說可以直接將符號丟棄,按照整數

n個整數全排列的遞歸實現C++

code clas 全排列 pop data turn ack popu perm 全排列是很經常使用的一個小算法,以下是n個整數全排列的遞歸實現,使用的是C++ #include <iostream> using namespace std; in

python的算法:二分法查找1

port == 歸類 算法 開始 log spa loop __name__ 1.什麽是二分法查找: 1.從數組的中間元素開始,如果中間元素正好是要查找的元素,則搜素過程結束; 2.如果某一特定元素大於或者小於中間元素,則在數組大於或小於中間元素的那一半中查找,而且跟開始

大數據江湖之即席查詢與分析下篇--手把手教你搭建即席查詢與分析Demo

dmi 安裝centos 用戶 author sla repo 相關 中文 plugin 上篇小弟分享了幾個“即席查詢與分析”的典型案例,引起了不少共鳴,好多小夥伴迫不及待地追問我們:說好的“手把手教你搭建即席查詢與分析Demo”啥時候能出?說到就得做到,差啥不能差