移动零
题目描述
解题思路
思路一:把数组中所有的0全部挑出来,组成一个新数组,然后和去除0的原数组合并
思路二:删除0,再在数组末尾插入0(注意扫描顺序,如果倒序则删0补0,如果顺序则删0后需注意数组长度与起始位置)
解题方法
- PHP
// 思路一
function moveZeroes(&$nums) {
$new = [];
foreach($nums as $k=>$v) {
if($v == 0) {
$new[] = $v;
unset($nums[$k]);
}
}
$arr = array_merge($nums, $new);
$nums = $arr;
return $nums;
}
// 思路二
function moveZeroes(&$nums) {
$len = count($nums);
for($i=$len-1;$i>=0;$i--) {
if($nums[$i] === 0) {
array_splice($nums, $i, 1);
array_push($nums,0);
}
}
return $nums;
}
// 思路三 以上两种方法的结合
function moveZeroes(&$nums) {
foreach($nums as $k=>$v) {
if($v===0) {
unset($nums[$k]);
array_push($nums, 0);
}
}
return $nums;
}
- GO
// 思路:先找出数组内所有非0的逐个放在前面,然后差几个在数组后补0
func moveZeroes(nums []int) []int{
len := len(nums)
j := 0
for i:=0;i<len;i++{
if(nums[i] != 0) {
nums[j] = nums[i]
j++
}
}
for j<len{
nums[j]=0
j++
}
return nums
}
//思路二:双指针有点像特别的交换方法
//左指针指向当前已经处理好的序列的尾部,右指针指向待处理序列的头部。
// 右指针不断向右移动,每次右指针指向非零数,则将左右指针对应的数交换,同时左指针右移。
func moveZeroes(nums []int) []int{
var left, right,len = 0, 0, len(nums)
for right <len {
if(nums[right] != 0) {
nums[left],nums[right] = nums[right], nums[left]
left++
}
right++
}
return nums
}
两数之和 II - 输入有序数组
题目描述
解题思路
在有序数组中寻找两个值相加为目标值,且不能重复利用。
可以一次循环该有序数组,以当前循环值为第一个目标值,然后在剩余的元素中寻找对应目标值
注意:剩余目标值一定在假设第一个目标值的右侧(不管是暴力循环还是二分法搜索都是可以实现的),还有就是一定要注意此题要求返回的索引是从 1 开始的
解题方法
- PHP
class Solution {
/**
* @param Integer[] $numbers
* @param Integer $target
* @return Integer[]
*/
function twoSum($numbers, $target) {
$len = count($numbers);
for($i=0;$i<$len;$i++) {
$find = $target-$numbers[$i];
$res = $this->search($numbers,$find,$i+1,$len-1);
if($res != -1) {
return [$i+1, $res+1];
}
}
return [];
}
function search($numbers, $find,$low,$high) {
while ($low <= $high) {
$mid = $low+floor(($high-$low)/2);
if($numbers[$mid] == $find) {
return $mid;
} else if($numbers[$mid] > $find) {
$high = $mid-1;
}else {
$low = $mid+1;
}
}
return -1;
}
}
- GO
// 同上思路: 循环数组后使用二分法搜索目标值
// 相同方式go的效率很明显比PHP要好很多呀
func twoSum(numbers []int, target int) []int {
var len = len(numbers)
for i,v := range numbers {
find := target-v
var low, high = i+1, len-1
for low <= high {
mid := low + (high-low)/2
if(numbers[mid] == find) {
return [] int {
i+1, mid+1}
} else if(numbers[mid] > find) {
high = mid-1
} else {
low = mid +1
}
}
}
return [] int{
}
}
// 思路二:双指针
// 两个指针分别指向最开始元素和最后元素,相加后与目标值比较,相同则返回索引;
// 相加值大于目标值,则右指针左移;反之则左指针右移
func twoSum(numbers []int, target int) []int {
var low, high = 0, len(numbers)-1
for low <= high {
find := numbers[low] + numbers[high]
if(find == target) {
return []int{
low+1, high+1}
}else if(find > target){
high--
}else{
low++
}
}
return [] int{
}
}